diff --git a/embedded/mkrouter-v06/.vs/mkrouter-v06/v14/.atsuo b/embedded/mkrouter-v06/.vs/mkrouter-v06/v14/.atsuo
new file mode 100644
index 0000000000000000000000000000000000000000..52b8e4141e14ce26e14977a42cb45c34b49fc6a6
Binary files /dev/null and b/embedded/mkrouter-v06/.vs/mkrouter-v06/v14/.atsuo differ
diff --git a/embedded/mkrouter-v06/mkrouter-v06.atsln b/embedded/mkrouter-v06/mkrouter-v06.atsln
new file mode 100644
index 0000000000000000000000000000000000000000..76bdcf9fe2da9a749352de4ee457be74f87754b2
--- /dev/null
+++ b/embedded/mkrouter-v06/mkrouter-v06.atsln
@@ -0,0 +1,22 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Atmel Studio Solution File, Format Version 11.00
+VisualStudioVersion = 14.0.23107.0
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{54F91283-7BC4-4236-8FF9-10F437C3AD48}") = "mkrouter-v06", "mkrouter-v06\mkrouter-v06.cproj", "{DCE6C7E3-EE26-4D79-826B-08594B9AD897}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|ARM = Debug|ARM
+		Release|ARM = Release|ARM
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{DCE6C7E3-EE26-4D79-826B-08594B9AD897}.Debug|ARM.ActiveCfg = Debug|ARM
+		{DCE6C7E3-EE26-4D79-826B-08594B9AD897}.Debug|ARM.Build.0 = Debug|ARM
+		{DCE6C7E3-EE26-4D79-826B-08594B9AD897}.Release|ARM.ActiveCfg = Release|ARM
+		{DCE6C7E3-EE26-4D79-826B-08594B9AD897}.Release|ARM.Build.0 = Release|ARM
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal
diff --git a/embedded/mkrouter-v06/mkrouter-v06/Debug/Makefile b/embedded/mkrouter-v06/mkrouter-v06/Debug/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..c430e4761704beffd30893aaf7e410bb43c1d9c2
--- /dev/null
+++ b/embedded/mkrouter-v06/mkrouter-v06/Debug/Makefile
@@ -0,0 +1,210 @@
+################################################################################
+# Automatically-generated file. Do not edit!
+################################################################################
+
+SHELL := cmd.exe
+RM := rm -rf
+
+USER_OBJS :=
+
+LIBS := 
+PROJ := 
+
+O_SRCS := 
+C_SRCS := 
+S_SRCS := 
+S_UPPER_SRCS := 
+OBJ_SRCS := 
+ASM_SRCS := 
+PREPROCESSING_SRCS := 
+OBJS := 
+OBJS_AS_ARGS := 
+C_DEPS := 
+C_DEPS_AS_ARGS := 
+EXECUTABLES := 
+OUTPUT_FILE_PATH :=
+OUTPUT_FILE_PATH_AS_ARGS :=
+AVR_APP_PATH :=$$$AVR_APP_PATH$$$
+QUOTE := "
+ADDITIONAL_DEPENDENCIES:=
+OUTPUT_FILE_DEP:=
+LIB_DEP:=
+LINKER_SCRIPT_DEP:=
+
+# Every subdirectory with source files must be described here
+SUBDIRS :=  \
+../Device_Startup/
+
+
+# Add inputs and outputs from these tool invocations to the build variables 
+C_SRCS +=  \
+../board_driver_serial.c \
+../board_driver_usb.c \
+../clock_init.c \
+../Device_Startup/startup_samd51.c \
+../Device_Startup/system_samd51.c \
+../main.c \
+../pin.c \
+../sam_ba_cdc.c \
+../sam_ba_monitor.c \
+../sam_ba_serial.c \
+../sam_ba_usb.c
+
+
+PREPROCESSING_SRCS += 
+
+
+ASM_SRCS += 
+
+
+OBJS +=  \
+board_driver_serial.o \
+board_driver_usb.o \
+clock_init.o \
+Device_Startup/startup_samd51.o \
+Device_Startup/system_samd51.o \
+main.o \
+pin.o \
+sam_ba_cdc.o \
+sam_ba_monitor.o \
+sam_ba_serial.o \
+sam_ba_usb.o
+
+OBJS_AS_ARGS +=  \
+board_driver_serial.o \
+board_driver_usb.o \
+clock_init.o \
+Device_Startup/startup_samd51.o \
+Device_Startup/system_samd51.o \
+main.o \
+pin.o \
+sam_ba_cdc.o \
+sam_ba_monitor.o \
+sam_ba_serial.o \
+sam_ba_usb.o
+
+C_DEPS +=  \
+board_driver_serial.d \
+board_driver_usb.d \
+clock_init.d \
+Device_Startup/startup_samd51.d \
+Device_Startup/system_samd51.d \
+main.d \
+pin.d \
+sam_ba_cdc.d \
+sam_ba_monitor.d \
+sam_ba_serial.d \
+sam_ba_usb.d
+
+C_DEPS_AS_ARGS +=  \
+board_driver_serial.d \
+board_driver_usb.d \
+clock_init.d \
+Device_Startup/startup_samd51.d \
+Device_Startup/system_samd51.d \
+main.d \
+pin.d \
+sam_ba_cdc.d \
+sam_ba_monitor.d \
+sam_ba_serial.d \
+sam_ba_usb.d
+
+OUTPUT_FILE_PATH +=mkrouter-v06.elf
+
+OUTPUT_FILE_PATH_AS_ARGS +=mkrouter-v06.elf
+
+ADDITIONAL_DEPENDENCIES:=
+
+OUTPUT_FILE_DEP:= ./makedep.mk
+
+LIB_DEP+= 
+
+LINKER_SCRIPT_DEP+=  \
+../Device_Startup/samd51j18a_flash.ld \
+../Device_Startup/samd51j18a_sram.ld
+
+
+# AVR32/GNU C Compiler
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+./%.o: .././%.c
+	@echo Building file: $<
+	@echo Invoking: ARM/GNU C Compiler : 6.3.1
+	$(QUOTE)C:\Program Files (x86)\Atmel\Studio\7.0\toolchain\arm\arm-gnu-toolchain\bin\arm-none-eabi-gcc.exe$(QUOTE)  -x c -mthumb -D__SAMD51J18A__ -DDEBUG  -I"C:\Program Files (x86)\Atmel\Studio\7.0\Packs\arm\CMSIS\5.0.1\CMSIS\Include" -I"C:\Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\SAMD51_DFP\1.0.70\include"  -O1 -ffunction-sections -mlong-calls -g3 -Wall -mcpu=cortex-m4 -c -std=gnu99 -MD -MP -MF "$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -MT"$(@:%.o=%.o)"   -o "$@" "$<" 
+	@echo Finished building: $<
+	
+
+Device_Startup/%.o: ../Device_Startup/%.c
+	@echo Building file: $<
+	@echo Invoking: ARM/GNU C Compiler : 6.3.1
+	$(QUOTE)C:\Program Files (x86)\Atmel\Studio\7.0\toolchain\arm\arm-gnu-toolchain\bin\arm-none-eabi-gcc.exe$(QUOTE)  -x c -mthumb -D__SAMD51J18A__ -DDEBUG  -I"C:\Program Files (x86)\Atmel\Studio\7.0\Packs\arm\CMSIS\5.0.1\CMSIS\Include" -I"C:\Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\SAMD51_DFP\1.0.70\include"  -O1 -ffunction-sections -mlong-calls -g3 -Wall -mcpu=cortex-m4 -c -std=gnu99 -MD -MP -MF "$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -MT"$(@:%.o=%.o)"   -o "$@" "$<" 
+	@echo Finished building: $<
+	
+
+
+
+# AVR32/GNU Preprocessing Assembler
+
+
+
+# AVR32/GNU Assembler
+
+
+
+
+ifneq ($(MAKECMDGOALS),clean)
+ifneq ($(strip $(C_DEPS)),)
+-include $(C_DEPS)
+endif
+endif
+
+# Add inputs and outputs from these tool invocations to the build variables 
+
+# All Target
+all: $(OUTPUT_FILE_PATH) $(ADDITIONAL_DEPENDENCIES)
+
+$(OUTPUT_FILE_PATH): $(OBJS) $(USER_OBJS) $(OUTPUT_FILE_DEP) $(LIB_DEP) $(LINKER_SCRIPT_DEP)
+	@echo Building target: $@
+	@echo Invoking: ARM/GNU Linker : 6.3.1
+	$(QUOTE)C:\Program Files (x86)\Atmel\Studio\7.0\toolchain\arm\arm-gnu-toolchain\bin\arm-none-eabi-gcc.exe$(QUOTE) -o$(OUTPUT_FILE_PATH_AS_ARGS) $(OBJS_AS_ARGS) $(USER_OBJS) $(LIBS) -mthumb -Wl,-Map="mkrouter-v06.map" -Wl,--start-group -lm  -Wl,--end-group -L"..\\Device_Startup"  -Wl,--gc-sections -mcpu=cortex-m4 -Tsamd51j18a_flash.ld  
+	@echo Finished building target: $@
+	"C:\Program Files (x86)\Atmel\Studio\7.0\toolchain\arm\arm-gnu-toolchain\bin\arm-none-eabi-objcopy.exe" -O binary "mkrouter-v06.elf" "mkrouter-v06.bin"
+	"C:\Program Files (x86)\Atmel\Studio\7.0\toolchain\arm\arm-gnu-toolchain\bin\arm-none-eabi-objcopy.exe" -O ihex -R .eeprom -R .fuse -R .lock -R .signature  "mkrouter-v06.elf" "mkrouter-v06.hex"
+	"C:\Program Files (x86)\Atmel\Studio\7.0\toolchain\arm\arm-gnu-toolchain\bin\arm-none-eabi-objcopy.exe" -j .eeprom --set-section-flags=.eeprom=alloc,load --change-section-lma .eeprom=0 --no-change-warnings -O binary "mkrouter-v06.elf" "mkrouter-v06.eep" || exit 0
+	"C:\Program Files (x86)\Atmel\Studio\7.0\toolchain\arm\arm-gnu-toolchain\bin\arm-none-eabi-objdump.exe" -h -S "mkrouter-v06.elf" > "mkrouter-v06.lss"
+	"C:\Program Files (x86)\Atmel\Studio\7.0\toolchain\arm\arm-gnu-toolchain\bin\arm-none-eabi-objcopy.exe" -O srec -R .eeprom -R .fuse -R .lock -R .signature  "mkrouter-v06.elf" "mkrouter-v06.srec"
+	"C:\Program Files (x86)\Atmel\Studio\7.0\toolchain\arm\arm-gnu-toolchain\bin\arm-none-eabi-size.exe" "mkrouter-v06.elf"
+	
+	
+
+
+
+
+
+# Other Targets
+clean:
+	-$(RM) $(OBJS_AS_ARGS) $(EXECUTABLES)  
+	-$(RM) $(C_DEPS_AS_ARGS)   
+	rm -rf "mkrouter-v06.elf" "mkrouter-v06.a" "mkrouter-v06.hex" "mkrouter-v06.bin" "mkrouter-v06.lss" "mkrouter-v06.eep" "mkrouter-v06.map" "mkrouter-v06.srec"
+	
\ No newline at end of file
diff --git a/embedded/mkrouter-v06/mkrouter-v06/Debug/makedep.mk b/embedded/mkrouter-v06/mkrouter-v06/Debug/makedep.mk
new file mode 100644
index 0000000000000000000000000000000000000000..076dc79f97e6694e90e95a3a8badf2416f58dba5
--- /dev/null
+++ b/embedded/mkrouter-v06/mkrouter-v06/Debug/makedep.mk
@@ -0,0 +1,26 @@
+################################################################################
+# Automatically-generated file. Do not edit or delete the file
+################################################################################
+
+board_driver_serial.c
+
+board_driver_usb.c
+
+clock_init.c
+
+Device_Startup\startup_samd51.c
+
+Device_Startup\system_samd51.c
+
+main.c
+
+pin.c
+
+sam_ba_cdc.c
+
+sam_ba_monitor.c
+
+sam_ba_serial.c
+
+sam_ba_usb.c
+
diff --git a/embedded/mkrouter-v06/mkrouter-v06/Debug/mkrouter-v06.eep b/embedded/mkrouter-v06/mkrouter-v06/Debug/mkrouter-v06.eep
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/embedded/mkrouter-v06/mkrouter-v06/Device_Startup/samd51j18a_flash.ld b/embedded/mkrouter-v06/mkrouter-v06/Device_Startup/samd51j18a_flash.ld
new file mode 100644
index 0000000000000000000000000000000000000000..301f100e83356376dbdd6191ac64239e551ae9c0
--- /dev/null
+++ b/embedded/mkrouter-v06/mkrouter-v06/Device_Startup/samd51j18a_flash.ld
@@ -0,0 +1,163 @@
+/**
+ * \file
+ *
+ * \brief Linker script for running in internal FLASH on the SAMD51J18A
+ *
+ * Copyright (c) 2017 Microchip Technology Inc.
+ *
+ * \asf_license_start
+ *
+ * \page License
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the Licence at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * \asf_license_stop
+ *
+ */
+
+
+OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
+OUTPUT_ARCH(arm)
+SEARCH_DIR(.)
+
+/* Memory Spaces Definitions */
+MEMORY
+{
+  rom      (rx)  : ORIGIN = 0x00000000, LENGTH = 0x00040000
+  ram      (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00020000
+  bkupram  (rwx) : ORIGIN = 0x47000000, LENGTH = 0x00002000
+  qspi     (rwx) : ORIGIN = 0x04000000, LENGTH = 0x01000000
+}
+
+/* The stack size used by the application. NOTE: you need to adjust according to your application. */
+STACK_SIZE = DEFINED(STACK_SIZE) ? STACK_SIZE : DEFINED(__stack_size__) ? __stack_size__ : 0x8000;
+
+/* 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(4);
+        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
+
+    .bkupram (NOLOAD):
+    {
+        . = ALIGN(8);
+        _sbkupram = .;
+        *(.bkupram .bkupram.*);
+        . = ALIGN(8);
+        _ebkupram = .;
+    } > bkupram
+
+    .qspi (NOLOAD):
+    {
+        . = ALIGN(8);
+        _sqspi = .;
+        *(.qspi .qspi.*);
+        . = ALIGN(8);
+        _eqspi = .;
+    } > qspi
+
+    /* .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);
+        _sstack = .;
+        . = . + STACK_SIZE;
+        . = ALIGN(8);
+        _estack = .;
+    } > ram
+
+    . = ALIGN(4);
+    _end = . ;
+}
diff --git a/embedded/mkrouter-v06/mkrouter-v06/Device_Startup/samd51j18a_sram.ld b/embedded/mkrouter-v06/mkrouter-v06/Device_Startup/samd51j18a_sram.ld
new file mode 100644
index 0000000000000000000000000000000000000000..0303f06c3a62e558ecfe4277dad36f8b5d5448d6
--- /dev/null
+++ b/embedded/mkrouter-v06/mkrouter-v06/Device_Startup/samd51j18a_sram.ld
@@ -0,0 +1,162 @@
+/**
+ * \file
+ *
+ * \brief Linker script for running in internal SRAM on the SAMD51J18A
+ *
+ * Copyright (c) 2017 Microchip Technology Inc.
+ *
+ * \asf_license_start
+ *
+ * \page License
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the Licence at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * \asf_license_stop
+ *
+ */
+
+
+OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
+OUTPUT_ARCH(arm)
+SEARCH_DIR(.)
+
+/* Memory Spaces Definitions */
+MEMORY
+{
+  ram      (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00020000
+  bkupram  (rwx) : ORIGIN = 0x47000000, LENGTH = 0x00002000
+  qspi     (rwx) : ORIGIN = 0x04000000, LENGTH = 0x01000000
+}
+
+/* The stack size used by the application. NOTE: you need to adjust according to your application. */
+STACK_SIZE = DEFINED(STACK_SIZE) ? STACK_SIZE : DEFINED(__stack_size__) ? __stack_size__ : 0x8000;
+
+/* 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(4);
+        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
+
+    /* .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);
+    _etext = .;
+
+    .relocate : AT (_etext)
+    {
+        . = ALIGN(4);
+        _srelocate = .;
+        *(.ramfunc .ramfunc.*);
+        *(.data .data.*);
+        . = ALIGN(4);
+        _erelocate = .;
+    } > ram
+
+    .bkupram (NOLOAD):
+    {
+        . = ALIGN(8);
+        _sbkupram = .;
+        *(.bkupram .bkupram.*);
+        . = ALIGN(8);
+        _ebkupram = .;
+    } > bkupram
+
+    .qspi (NOLOAD):
+    {
+        . = ALIGN(8);
+        _sqspi = .;
+        *(.qspi .qspi.*);
+        . = ALIGN(8);
+        _eqspi = .;
+    } > qspi
+
+    /* .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);
+        _sstack = .;
+        . = . + STACK_SIZE;
+        . = ALIGN(8);
+        _estack = .;
+    } > ram
+
+    . = ALIGN(4);
+    _end = . ;
+}
diff --git a/embedded/mkrouter-v06/mkrouter-v06/Device_Startup/startup_samd51.c b/embedded/mkrouter-v06/mkrouter-v06/Device_Startup/startup_samd51.c
new file mode 100644
index 0000000000000000000000000000000000000000..a62d02f1ca57aa2d3ef1ba50af1751639e5e316c
--- /dev/null
+++ b/embedded/mkrouter-v06/mkrouter-v06/Device_Startup/startup_samd51.c
@@ -0,0 +1,548 @@
+/**
+ * \file
+ *
+ * \brief gcc starttup file for SAMD51
+ *
+ * Copyright (c) 2017 Microchip Technology Inc.
+ *
+ * \asf_license_start
+ *
+ * \page License
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the Licence at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * \asf_license_stop
+ *
+ */
+
+#include "samd51.h"
+
+/* 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;
+extern uint32_t _sstack;
+extern uint32_t _estack;
+
+/** \cond DOXYGEN_SHOULD_SKIP_THIS */
+int main(void);
+/** \endcond */
+
+void __libc_init_array(void);
+
+/* Default empty handler */
+void Dummy_Handler(void);
+
+/* Cortex-M4 core handlers */
+void NMI_Handler             ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
+void HardFault_Handler       ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
+void MemManage_Handler       ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
+void BusFault_Handler        ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
+void UsageFault_Handler      ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
+void SVC_Handler             ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
+void DebugMon_Handler        ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
+void PendSV_Handler          ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
+void SysTick_Handler         ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
+
+/* Peripherals handlers */
+void PM_Handler              ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
+void MCLK_Handler            ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
+void OSCCTRL_0_Handler       ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* OSCCTRL_XOSCFAIL_0, OSCCTRL_XOSCRDY_0 */
+void OSCCTRL_1_Handler       ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* OSCCTRL_XOSCFAIL_1, OSCCTRL_XOSCRDY_1 */
+void OSCCTRL_2_Handler       ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* OSCCTRL_DFLLLOCKC, OSCCTRL_DFLLLOCKF, OSCCTRL_DFLLOOB, OSCCTRL_DFLLRCS, OSCCTRL_DFLLRDY */
+void OSCCTRL_3_Handler       ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* OSCCTRL_DPLLLCKF_0, OSCCTRL_DPLLLCKR_0, OSCCTRL_DPLLLDRTO_0, OSCCTRL_DPLLLTO_0 */
+void OSCCTRL_4_Handler       ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* OSCCTRL_DPLLLCKF_1, OSCCTRL_DPLLLCKR_1, OSCCTRL_DPLLLDRTO_1, OSCCTRL_DPLLLTO_1 */
+void OSC32KCTRL_Handler      ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
+void SUPC_0_Handler          ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* SUPC_B12SRDY, SUPC_B33SRDY, SUPC_BOD12RDY, SUPC_BOD33RDY, SUPC_VCORERDY, SUPC_VREGRDY */
+void SUPC_1_Handler          ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* SUPC_BOD12DET, SUPC_BOD33DET */
+void WDT_Handler             ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
+void RTC_Handler             ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
+void EIC_0_Handler           ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* EIC_EXTINT_0 */
+void EIC_1_Handler           ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* EIC_EXTINT_1 */
+void EIC_2_Handler           ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* EIC_EXTINT_2 */
+void EIC_3_Handler           ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* EIC_EXTINT_3 */
+void EIC_4_Handler           ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* EIC_EXTINT_4 */
+void EIC_5_Handler           ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* EIC_EXTINT_5 */
+void EIC_6_Handler           ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* EIC_EXTINT_6 */
+void EIC_7_Handler           ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* EIC_EXTINT_7 */
+void EIC_8_Handler           ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* EIC_EXTINT_8 */
+void EIC_9_Handler           ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* EIC_EXTINT_9 */
+void EIC_10_Handler          ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* EIC_EXTINT_10 */
+void EIC_11_Handler          ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* EIC_EXTINT_11 */
+void EIC_12_Handler          ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* EIC_EXTINT_12 */
+void EIC_13_Handler          ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* EIC_EXTINT_13 */
+void EIC_14_Handler          ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* EIC_EXTINT_14 */
+void EIC_15_Handler          ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* EIC_EXTINT_15 */
+void FREQM_Handler           ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
+void NVMCTRL_0_Handler       ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* NVMCTRL_0, NVMCTRL_1, NVMCTRL_2, NVMCTRL_3, NVMCTRL_4, NVMCTRL_5, NVMCTRL_6, NVMCTRL_7 */
+void NVMCTRL_1_Handler       ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* NVMCTRL_10, NVMCTRL_8, NVMCTRL_9 */
+void DMAC_0_Handler          ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* DMAC_SUSP_0, DMAC_TCMPL_0, DMAC_TERR_0 */
+void DMAC_1_Handler          ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* DMAC_SUSP_1, DMAC_TCMPL_1, DMAC_TERR_1 */
+void DMAC_2_Handler          ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* DMAC_SUSP_2, DMAC_TCMPL_2, DMAC_TERR_2 */
+void DMAC_3_Handler          ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* DMAC_SUSP_3, DMAC_TCMPL_3, DMAC_TERR_3 */
+void DMAC_4_Handler          ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* DMAC_SUSP_10, DMAC_SUSP_11, DMAC_SUSP_12, DMAC_SUSP_13, DMAC_SUSP_14, DMAC_SUSP_15, DMAC_SUSP_16, DMAC_SUSP_17, DMAC_SUSP_18, DMAC_SUSP_19, DMAC_SUSP_20, DMAC_SUSP_21, DMAC_SUSP_22, DMAC_SUSP_23, DMAC_SUSP_24, DMAC_SUSP_25, DMAC_SUSP_26, DMAC_SUSP_27, DMAC_SUSP_28, DMAC_SUSP_29, DMAC_SUSP_30, DMAC_SUSP_31, DMAC_SUSP_4, DMAC_SUSP_5, DMAC_SUSP_6, DMAC_SUSP_7, DMAC_SUSP_8, DMAC_SUSP_9, DMAC_TCMPL_10, DMAC_TCMPL_11, DMAC_TCMPL_12, DMAC_TCMPL_13, DMAC_TCMPL_14, DMAC_TCMPL_15, DMAC_TCMPL_16, DMAC_TCMPL_17, DMAC_TCMPL_18, DMAC_TCMPL_19, DMAC_TCMPL_20, DMAC_TCMPL_21, DMAC_TCMPL_22, DMAC_TCMPL_23, DMAC_TCMPL_24, DMAC_TCMPL_25, DMAC_TCMPL_26, DMAC_TCMPL_27, DMAC_TCMPL_28, DMAC_TCMPL_29, DMAC_TCMPL_30, DMAC_TCMPL_31, DMAC_TCMPL_4, DMAC_TCMPL_5, DMAC_TCMPL_6, DMAC_TCMPL_7, DMAC_TCMPL_8, DMAC_TCMPL_9, DMAC_TERR_10, DMAC_TERR_11, DMAC_TERR_12, DMAC_TERR_13, DMAC_TERR_14, DMAC_TERR_15, DMAC_TERR_16, DMAC_TERR_17, DMAC_TERR_18, DMAC_TERR_19, DMAC_TERR_20, DMAC_TERR_21, DMAC_TERR_22, DMAC_TERR_23, DMAC_TERR_24, DMAC_TERR_25, DMAC_TERR_26, DMAC_TERR_27, DMAC_TERR_28, DMAC_TERR_29, DMAC_TERR_30, DMAC_TERR_31, DMAC_TERR_4, DMAC_TERR_5, DMAC_TERR_6, DMAC_TERR_7, DMAC_TERR_8, DMAC_TERR_9 */
+void EVSYS_0_Handler         ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* EVSYS_EVD_0, EVSYS_OVR_0 */
+void EVSYS_1_Handler         ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* EVSYS_EVD_1, EVSYS_OVR_1 */
+void EVSYS_2_Handler         ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* EVSYS_EVD_2, EVSYS_OVR_2 */
+void EVSYS_3_Handler         ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* EVSYS_EVD_3, EVSYS_OVR_3 */
+void EVSYS_4_Handler         ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* EVSYS_EVD_10, EVSYS_EVD_11, EVSYS_EVD_4, EVSYS_EVD_5, EVSYS_EVD_6, EVSYS_EVD_7, EVSYS_EVD_8, EVSYS_EVD_9, EVSYS_OVR_10, EVSYS_OVR_11, EVSYS_OVR_4, EVSYS_OVR_5, EVSYS_OVR_6, EVSYS_OVR_7, EVSYS_OVR_8, EVSYS_OVR_9 */
+void PAC_Handler             ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
+void TAL_0_Handler           ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* TAL_BRK */
+void TAL_1_Handler           ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* TAL_IPS_0, TAL_IPS_1 */
+void RAMECC_Handler          ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
+void SERCOM0_0_Handler       ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* SERCOM0_0 */
+void SERCOM0_1_Handler       ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* SERCOM0_1 */
+void SERCOM0_2_Handler       ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* SERCOM0_2 */
+void SERCOM0_3_Handler       ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* SERCOM0_3, SERCOM0_4, SERCOM0_5, SERCOM0_6 */
+void SERCOM1_0_Handler       ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* SERCOM1_0 */
+void SERCOM1_1_Handler       ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* SERCOM1_1 */
+void SERCOM1_2_Handler       ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* SERCOM1_2 */
+void SERCOM1_3_Handler       ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* SERCOM1_3, SERCOM1_4, SERCOM1_5, SERCOM1_6 */
+void SERCOM2_0_Handler       ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* SERCOM2_0 */
+void SERCOM2_1_Handler       ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* SERCOM2_1 */
+void SERCOM2_2_Handler       ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* SERCOM2_2 */
+void SERCOM2_3_Handler       ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* SERCOM2_3, SERCOM2_4, SERCOM2_5, SERCOM2_6 */
+void SERCOM3_0_Handler       ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* SERCOM3_0 */
+void SERCOM3_1_Handler       ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* SERCOM3_1 */
+void SERCOM3_2_Handler       ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* SERCOM3_2 */
+void SERCOM3_3_Handler       ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* SERCOM3_3, SERCOM3_4, SERCOM3_5, SERCOM3_6 */
+#ifdef ID_SERCOM4
+void SERCOM4_0_Handler       ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* SERCOM4_0 */
+void SERCOM4_1_Handler       ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* SERCOM4_1 */
+void SERCOM4_2_Handler       ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* SERCOM4_2 */
+void SERCOM4_3_Handler       ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* SERCOM4_3, SERCOM4_4, SERCOM4_5, SERCOM4_6 */
+#endif
+#ifdef ID_SERCOM5
+void SERCOM5_0_Handler       ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* SERCOM5_0 */
+void SERCOM5_1_Handler       ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* SERCOM5_1 */
+void SERCOM5_2_Handler       ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* SERCOM5_2 */
+void SERCOM5_3_Handler       ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* SERCOM5_3, SERCOM5_4, SERCOM5_5, SERCOM5_6 */
+#endif
+#ifdef ID_SERCOM6
+void SERCOM6_0_Handler       ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* SERCOM6_0 */
+void SERCOM6_1_Handler       ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* SERCOM6_1 */
+void SERCOM6_2_Handler       ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* SERCOM6_2 */
+void SERCOM6_3_Handler       ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* SERCOM6_3, SERCOM6_4, SERCOM6_5, SERCOM6_6 */
+#endif
+#ifdef ID_SERCOM7
+void SERCOM7_0_Handler       ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* SERCOM7_0 */
+void SERCOM7_1_Handler       ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* SERCOM7_1 */
+void SERCOM7_2_Handler       ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* SERCOM7_2 */
+void SERCOM7_3_Handler       ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* SERCOM7_3, SERCOM7_4, SERCOM7_5, SERCOM7_6 */
+#endif
+#ifdef ID_CAN0
+void CAN0_Handler            ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
+#endif
+#ifdef ID_CAN1
+void CAN1_Handler            ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
+#endif
+#ifdef ID_USB
+void USB_0_Handler           ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* USB_EORSM_DNRSM, USB_EORST_RST, USB_LPMSUSP_DDISC, USB_LPM_DCONN, USB_MSOF, USB_RAMACER, USB_RXSTP_TXSTP_0, USB_RXSTP_TXSTP_1, USB_RXSTP_TXSTP_2, USB_RXSTP_TXSTP_3, USB_RXSTP_TXSTP_4, USB_RXSTP_TXSTP_5, USB_RXSTP_TXSTP_6, USB_RXSTP_TXSTP_7, USB_STALL0_STALL_0, USB_STALL0_STALL_1, USB_STALL0_STALL_2, USB_STALL0_STALL_3, USB_STALL0_STALL_4, USB_STALL0_STALL_5, USB_STALL0_STALL_6, USB_STALL0_STALL_7, USB_STALL1_0, USB_STALL1_1, USB_STALL1_2, USB_STALL1_3, USB_STALL1_4, USB_STALL1_5, USB_STALL1_6, USB_STALL1_7, USB_SUSPEND, USB_TRFAIL0_TRFAIL_0, USB_TRFAIL0_TRFAIL_1, USB_TRFAIL0_TRFAIL_2, USB_TRFAIL0_TRFAIL_3, USB_TRFAIL0_TRFAIL_4, USB_TRFAIL0_TRFAIL_5, USB_TRFAIL0_TRFAIL_6, USB_TRFAIL0_TRFAIL_7, USB_TRFAIL1_PERR_0, USB_TRFAIL1_PERR_1, USB_TRFAIL1_PERR_2, USB_TRFAIL1_PERR_3, USB_TRFAIL1_PERR_4, USB_TRFAIL1_PERR_5, USB_TRFAIL1_PERR_6, USB_TRFAIL1_PERR_7, USB_UPRSM, USB_WAKEUP */
+void USB_1_Handler           ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* USB_SOF_HSOF */
+void USB_2_Handler           ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* USB_TRCPT0_0, USB_TRCPT0_1, USB_TRCPT0_2, USB_TRCPT0_3, USB_TRCPT0_4, USB_TRCPT0_5, USB_TRCPT0_6, USB_TRCPT0_7 */
+void USB_3_Handler           ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* USB_TRCPT1_0, USB_TRCPT1_1, USB_TRCPT1_2, USB_TRCPT1_3, USB_TRCPT1_4, USB_TRCPT1_5, USB_TRCPT1_6, USB_TRCPT1_7 */
+#endif
+#ifdef ID_GMAC
+void GMAC_Handler            ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
+#endif
+void TCC0_0_Handler          ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* TCC0_CNT_A, TCC0_DFS_A, TCC0_ERR_A, TCC0_FAULT0_A, TCC0_FAULT1_A, TCC0_FAULTA_A, TCC0_FAULTB_A, TCC0_OVF, TCC0_TRG, TCC0_UFS_A */
+void TCC0_1_Handler          ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* TCC0_MC_0 */
+void TCC0_2_Handler          ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* TCC0_MC_1 */
+void TCC0_3_Handler          ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* TCC0_MC_2 */
+void TCC0_4_Handler          ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* TCC0_MC_3 */
+void TCC0_5_Handler          ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* TCC0_MC_4 */
+void TCC0_6_Handler          ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* TCC0_MC_5 */
+void TCC1_0_Handler          ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* TCC1_CNT_A, TCC1_DFS_A, TCC1_ERR_A, TCC1_FAULT0_A, TCC1_FAULT1_A, TCC1_FAULTA_A, TCC1_FAULTB_A, TCC1_OVF, TCC1_TRG, TCC1_UFS_A */
+void TCC1_1_Handler          ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* TCC1_MC_0 */
+void TCC1_2_Handler          ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* TCC1_MC_1 */
+void TCC1_3_Handler          ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* TCC1_MC_2 */
+void TCC1_4_Handler          ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* TCC1_MC_3 */
+void TCC2_0_Handler          ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* TCC2_CNT_A, TCC2_DFS_A, TCC2_ERR_A, TCC2_FAULT0_A, TCC2_FAULT1_A, TCC2_FAULTA_A, TCC2_FAULTB_A, TCC2_OVF, TCC2_TRG, TCC2_UFS_A */
+void TCC2_1_Handler          ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* TCC2_MC_0 */
+void TCC2_2_Handler          ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* TCC2_MC_1 */
+void TCC2_3_Handler          ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* TCC2_MC_2 */
+#ifdef ID_TCC3
+void TCC3_0_Handler          ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* TCC3_CNT_A, TCC3_DFS_A, TCC3_ERR_A, TCC3_FAULT0_A, TCC3_FAULT1_A, TCC3_FAULTA_A, TCC3_FAULTB_A, TCC3_OVF, TCC3_TRG, TCC3_UFS_A */
+void TCC3_1_Handler          ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* TCC3_MC_0 */
+void TCC3_2_Handler          ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* TCC3_MC_1 */
+#endif
+#ifdef ID_TCC4
+void TCC4_0_Handler          ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* TCC4_CNT_A, TCC4_DFS_A, TCC4_ERR_A, TCC4_FAULT0_A, TCC4_FAULT1_A, TCC4_FAULTA_A, TCC4_FAULTB_A, TCC4_OVF, TCC4_TRG, TCC4_UFS_A */
+void TCC4_1_Handler          ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* TCC4_MC_0 */
+void TCC4_2_Handler          ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* TCC4_MC_1 */
+#endif
+void TC0_Handler             ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
+void TC1_Handler             ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
+void TC2_Handler             ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
+void TC3_Handler             ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
+#ifdef ID_TC4
+void TC4_Handler             ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
+#endif
+#ifdef ID_TC5
+void TC5_Handler             ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
+#endif
+#ifdef ID_TC6
+void TC6_Handler             ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
+#endif
+#ifdef ID_TC7
+void TC7_Handler             ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
+#endif
+void PDEC_0_Handler          ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* PDEC_DIR_A, PDEC_ERR_A, PDEC_OVF, PDEC_VLC_A */
+void PDEC_1_Handler          ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* PDEC_MC_0 */
+void PDEC_2_Handler          ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* PDEC_MC_1 */
+void ADC0_0_Handler          ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* ADC0_OVERRUN, ADC0_WINMON */
+void ADC0_1_Handler          ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* ADC0_RESRDY */
+void ADC1_0_Handler          ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* ADC1_OVERRUN, ADC1_WINMON */
+void ADC1_1_Handler          ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* ADC1_RESRDY */
+void AC_Handler              ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
+void DAC_0_Handler           ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* DAC_OVERRUN_A_0, DAC_OVERRUN_A_1, DAC_UNDERRUN_A_0, DAC_UNDERRUN_A_1 */
+void DAC_1_Handler           ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* DAC_EMPTY_0 */
+void DAC_2_Handler           ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* DAC_EMPTY_1 */
+void DAC_3_Handler           ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* DAC_RESRDY_0 */
+void DAC_4_Handler           ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* DAC_RESRDY_1 */
+#ifdef ID_I2S
+void I2S_Handler             ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
+#endif
+void PCC_Handler             ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
+void AES_Handler             ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
+void TRNG_Handler            ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
+#ifdef ID_ICM
+void ICM_Handler             ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
+#endif
+#ifdef ID_PUKCC
+void PUKCC_Handler           ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
+#endif
+void QSPI_Handler            ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
+#ifdef ID_SDHC0
+void SDHC0_Handler           ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
+#endif
+#ifdef ID_SDHC1
+void SDHC1_Handler           ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
+#endif
+
+/* Exception Table */
+__attribute__ ((section(".vectors")))
+const DeviceVectors exception_table = {
+
+        /* Configure Initial Stack Pointer, using linker-generated symbols */
+        .pvStack                = (void*) (&_estack),
+
+        .pfnReset_Handler       = (void*) Reset_Handler,
+        .pfnNMI_Handler         = (void*) NMI_Handler,
+        .pfnHardFault_Handler   = (void*) HardFault_Handler,
+        .pfnMemManage_Handler   = (void*) MemManage_Handler,
+        .pfnBusFault_Handler    = (void*) BusFault_Handler,
+        .pfnUsageFault_Handler  = (void*) UsageFault_Handler,
+        .pvReservedM9           = (void*) (0UL), /* Reserved */
+        .pvReservedM8           = (void*) (0UL), /* Reserved */
+        .pvReservedM7           = (void*) (0UL), /* Reserved */
+        .pvReservedM6           = (void*) (0UL), /* Reserved */
+        .pfnSVC_Handler         = (void*) SVC_Handler,
+        .pfnDebugMon_Handler    = (void*) DebugMon_Handler,
+        .pvReservedM3           = (void*) (0UL), /* Reserved */
+        .pfnPendSV_Handler      = (void*) PendSV_Handler,
+        .pfnSysTick_Handler     = (void*) SysTick_Handler,
+
+        /* Configurable interrupts */
+        .pfnPM_Handler          = (void*) PM_Handler,             /*  0 Power Manager */
+        .pfnMCLK_Handler        = (void*) MCLK_Handler,           /*  1 Main Clock */
+        .pfnOSCCTRL_0_Handler   = (void*) OSCCTRL_0_Handler,      /*  2 OSCCTRL_XOSCFAIL_0, OSCCTRL_XOSCRDY_0 */
+        .pfnOSCCTRL_1_Handler   = (void*) OSCCTRL_1_Handler,      /*  3 OSCCTRL_XOSCFAIL_1, OSCCTRL_XOSCRDY_1 */
+        .pfnOSCCTRL_2_Handler   = (void*) OSCCTRL_2_Handler,      /*  4 OSCCTRL_DFLLLOCKC, OSCCTRL_DFLLLOCKF, OSCCTRL_DFLLOOB, OSCCTRL_DFLLRCS, OSCCTRL_DFLLRDY */
+        .pfnOSCCTRL_3_Handler   = (void*) OSCCTRL_3_Handler,      /*  5 OSCCTRL_DPLLLCKF_0, OSCCTRL_DPLLLCKR_0, OSCCTRL_DPLLLDRTO_0, OSCCTRL_DPLLLTO_0 */
+        .pfnOSCCTRL_4_Handler   = (void*) OSCCTRL_4_Handler,      /*  6 OSCCTRL_DPLLLCKF_1, OSCCTRL_DPLLLCKR_1, OSCCTRL_DPLLLDRTO_1, OSCCTRL_DPLLLTO_1 */
+        .pfnOSC32KCTRL_Handler  = (void*) OSC32KCTRL_Handler,     /*  7 32kHz Oscillators Control */
+        .pfnSUPC_0_Handler      = (void*) SUPC_0_Handler,         /*  8 SUPC_B12SRDY, SUPC_B33SRDY, SUPC_BOD12RDY, SUPC_BOD33RDY, SUPC_VCORERDY, SUPC_VREGRDY */
+        .pfnSUPC_1_Handler      = (void*) SUPC_1_Handler,         /*  9 SUPC_BOD12DET, SUPC_BOD33DET */
+        .pfnWDT_Handler         = (void*) WDT_Handler,            /* 10 Watchdog Timer */
+        .pfnRTC_Handler         = (void*) RTC_Handler,            /* 11 Real-Time Counter */
+        .pfnEIC_0_Handler       = (void*) EIC_0_Handler,          /* 12 EIC_EXTINT_0 */
+        .pfnEIC_1_Handler       = (void*) EIC_1_Handler,          /* 13 EIC_EXTINT_1 */
+        .pfnEIC_2_Handler       = (void*) EIC_2_Handler,          /* 14 EIC_EXTINT_2 */
+        .pfnEIC_3_Handler       = (void*) EIC_3_Handler,          /* 15 EIC_EXTINT_3 */
+        .pfnEIC_4_Handler       = (void*) EIC_4_Handler,          /* 16 EIC_EXTINT_4 */
+        .pfnEIC_5_Handler       = (void*) EIC_5_Handler,          /* 17 EIC_EXTINT_5 */
+        .pfnEIC_6_Handler       = (void*) EIC_6_Handler,          /* 18 EIC_EXTINT_6 */
+        .pfnEIC_7_Handler       = (void*) EIC_7_Handler,          /* 19 EIC_EXTINT_7 */
+        .pfnEIC_8_Handler       = (void*) EIC_8_Handler,          /* 20 EIC_EXTINT_8 */
+        .pfnEIC_9_Handler       = (void*) EIC_9_Handler,          /* 21 EIC_EXTINT_9 */
+        .pfnEIC_10_Handler      = (void*) EIC_10_Handler,         /* 22 EIC_EXTINT_10 */
+        .pfnEIC_11_Handler      = (void*) EIC_11_Handler,         /* 23 EIC_EXTINT_11 */
+        .pfnEIC_12_Handler      = (void*) EIC_12_Handler,         /* 24 EIC_EXTINT_12 */
+        .pfnEIC_13_Handler      = (void*) EIC_13_Handler,         /* 25 EIC_EXTINT_13 */
+        .pfnEIC_14_Handler      = (void*) EIC_14_Handler,         /* 26 EIC_EXTINT_14 */
+        .pfnEIC_15_Handler      = (void*) EIC_15_Handler,         /* 27 EIC_EXTINT_15 */
+        .pfnFREQM_Handler       = (void*) FREQM_Handler,          /* 28 Frequency Meter */
+        .pfnNVMCTRL_0_Handler   = (void*) NVMCTRL_0_Handler,      /* 29 NVMCTRL_0, NVMCTRL_1, NVMCTRL_2, NVMCTRL_3, NVMCTRL_4, NVMCTRL_5, NVMCTRL_6, NVMCTRL_7 */
+        .pfnNVMCTRL_1_Handler   = (void*) NVMCTRL_1_Handler,      /* 30 NVMCTRL_10, NVMCTRL_8, NVMCTRL_9 */
+        .pfnDMAC_0_Handler      = (void*) DMAC_0_Handler,         /* 31 DMAC_SUSP_0, DMAC_TCMPL_0, DMAC_TERR_0 */
+        .pfnDMAC_1_Handler      = (void*) DMAC_1_Handler,         /* 32 DMAC_SUSP_1, DMAC_TCMPL_1, DMAC_TERR_1 */
+        .pfnDMAC_2_Handler      = (void*) DMAC_2_Handler,         /* 33 DMAC_SUSP_2, DMAC_TCMPL_2, DMAC_TERR_2 */
+        .pfnDMAC_3_Handler      = (void*) DMAC_3_Handler,         /* 34 DMAC_SUSP_3, DMAC_TCMPL_3, DMAC_TERR_3 */
+        .pfnDMAC_4_Handler      = (void*) DMAC_4_Handler,         /* 35 DMAC_SUSP_10, DMAC_SUSP_11, DMAC_SUSP_12, DMAC_SUSP_13, DMAC_SUSP_14, DMAC_SUSP_15, DMAC_SUSP_16, DMAC_SUSP_17, DMAC_SUSP_18, DMAC_SUSP_19, DMAC_SUSP_20, DMAC_SUSP_21, DMAC_SUSP_22, DMAC_SUSP_23, DMAC_SUSP_24, DMAC_SUSP_25, DMAC_SUSP_26, DMAC_SUSP_27, DMAC_SUSP_28, DMAC_SUSP_29, DMAC_SUSP_30, DMAC_SUSP_31, DMAC_SUSP_4, DMAC_SUSP_5, DMAC_SUSP_6, DMAC_SUSP_7, DMAC_SUSP_8, DMAC_SUSP_9, DMAC_TCMPL_10, DMAC_TCMPL_11, DMAC_TCMPL_12, DMAC_TCMPL_13, DMAC_TCMPL_14, DMAC_TCMPL_15, DMAC_TCMPL_16, DMAC_TCMPL_17, DMAC_TCMPL_18, DMAC_TCMPL_19, DMAC_TCMPL_20, DMAC_TCMPL_21, DMAC_TCMPL_22, DMAC_TCMPL_23, DMAC_TCMPL_24, DMAC_TCMPL_25, DMAC_TCMPL_26, DMAC_TCMPL_27, DMAC_TCMPL_28, DMAC_TCMPL_29, DMAC_TCMPL_30, DMAC_TCMPL_31, DMAC_TCMPL_4, DMAC_TCMPL_5, DMAC_TCMPL_6, DMAC_TCMPL_7, DMAC_TCMPL_8, DMAC_TCMPL_9, DMAC_TERR_10, DMAC_TERR_11, DMAC_TERR_12, DMAC_TERR_13, DMAC_TERR_14, DMAC_TERR_15, DMAC_TERR_16, DMAC_TERR_17, DMAC_TERR_18, DMAC_TERR_19, DMAC_TERR_20, DMAC_TERR_21, DMAC_TERR_22, DMAC_TERR_23, DMAC_TERR_24, DMAC_TERR_25, DMAC_TERR_26, DMAC_TERR_27, DMAC_TERR_28, DMAC_TERR_29, DMAC_TERR_30, DMAC_TERR_31, DMAC_TERR_4, DMAC_TERR_5, DMAC_TERR_6, DMAC_TERR_7, DMAC_TERR_8, DMAC_TERR_9 */
+        .pfnEVSYS_0_Handler     = (void*) EVSYS_0_Handler,        /* 36 EVSYS_EVD_0, EVSYS_OVR_0 */
+        .pfnEVSYS_1_Handler     = (void*) EVSYS_1_Handler,        /* 37 EVSYS_EVD_1, EVSYS_OVR_1 */
+        .pfnEVSYS_2_Handler     = (void*) EVSYS_2_Handler,        /* 38 EVSYS_EVD_2, EVSYS_OVR_2 */
+        .pfnEVSYS_3_Handler     = (void*) EVSYS_3_Handler,        /* 39 EVSYS_EVD_3, EVSYS_OVR_3 */
+        .pfnEVSYS_4_Handler     = (void*) EVSYS_4_Handler,        /* 40 EVSYS_EVD_10, EVSYS_EVD_11, EVSYS_EVD_4, EVSYS_EVD_5, EVSYS_EVD_6, EVSYS_EVD_7, EVSYS_EVD_8, EVSYS_EVD_9, EVSYS_OVR_10, EVSYS_OVR_11, EVSYS_OVR_4, EVSYS_OVR_5, EVSYS_OVR_6, EVSYS_OVR_7, EVSYS_OVR_8, EVSYS_OVR_9 */
+        .pfnPAC_Handler         = (void*) PAC_Handler,            /* 41 Peripheral Access Controller */
+        .pfnTAL_0_Handler       = (void*) TAL_0_Handler,          /* 42 TAL_BRK */
+        .pfnTAL_1_Handler       = (void*) TAL_1_Handler,          /* 43 TAL_IPS_0, TAL_IPS_1 */
+        .pvReserved44           = (void*) (0UL),                  /* 44 Reserved */
+        .pfnRAMECC_Handler      = (void*) RAMECC_Handler,         /* 45 RAM ECC */
+        .pfnSERCOM0_0_Handler   = (void*) SERCOM0_0_Handler,      /* 46 SERCOM0_0 */
+        .pfnSERCOM0_1_Handler   = (void*) SERCOM0_1_Handler,      /* 47 SERCOM0_1 */
+        .pfnSERCOM0_2_Handler   = (void*) SERCOM0_2_Handler,      /* 48 SERCOM0_2 */
+        .pfnSERCOM0_3_Handler   = (void*) SERCOM0_3_Handler,      /* 49 SERCOM0_3, SERCOM0_4, SERCOM0_5, SERCOM0_6 */
+        .pfnSERCOM1_0_Handler   = (void*) SERCOM1_0_Handler,      /* 50 SERCOM1_0 */
+        .pfnSERCOM1_1_Handler   = (void*) SERCOM1_1_Handler,      /* 51 SERCOM1_1 */
+        .pfnSERCOM1_2_Handler   = (void*) SERCOM1_2_Handler,      /* 52 SERCOM1_2 */
+        .pfnSERCOM1_3_Handler   = (void*) SERCOM1_3_Handler,      /* 53 SERCOM1_3, SERCOM1_4, SERCOM1_5, SERCOM1_6 */
+        .pfnSERCOM2_0_Handler   = (void*) SERCOM2_0_Handler,      /* 54 SERCOM2_0 */
+        .pfnSERCOM2_1_Handler   = (void*) SERCOM2_1_Handler,      /* 55 SERCOM2_1 */
+        .pfnSERCOM2_2_Handler   = (void*) SERCOM2_2_Handler,      /* 56 SERCOM2_2 */
+        .pfnSERCOM2_3_Handler   = (void*) SERCOM2_3_Handler,      /* 57 SERCOM2_3, SERCOM2_4, SERCOM2_5, SERCOM2_6 */
+        .pfnSERCOM3_0_Handler   = (void*) SERCOM3_0_Handler,      /* 58 SERCOM3_0 */
+        .pfnSERCOM3_1_Handler   = (void*) SERCOM3_1_Handler,      /* 59 SERCOM3_1 */
+        .pfnSERCOM3_2_Handler   = (void*) SERCOM3_2_Handler,      /* 60 SERCOM3_2 */
+        .pfnSERCOM3_3_Handler   = (void*) SERCOM3_3_Handler,      /* 61 SERCOM3_3, SERCOM3_4, SERCOM3_5, SERCOM3_6 */
+#ifdef ID_SERCOM4
+        .pfnSERCOM4_0_Handler   = (void*) SERCOM4_0_Handler,      /* 62 SERCOM4_0 */
+        .pfnSERCOM4_1_Handler   = (void*) SERCOM4_1_Handler,      /* 63 SERCOM4_1 */
+        .pfnSERCOM4_2_Handler   = (void*) SERCOM4_2_Handler,      /* 64 SERCOM4_2 */
+        .pfnSERCOM4_3_Handler   = (void*) SERCOM4_3_Handler,      /* 65 SERCOM4_3, SERCOM4_4, SERCOM4_5, SERCOM4_6 */
+#else
+        .pvReserved62           = (void*) (0UL),                  /* 62 Reserved */
+        .pvReserved63           = (void*) (0UL),                  /* 63 Reserved */
+        .pvReserved64           = (void*) (0UL),                  /* 64 Reserved */
+        .pvReserved65           = (void*) (0UL),                  /* 65 Reserved */
+#endif
+#ifdef ID_SERCOM5
+        .pfnSERCOM5_0_Handler   = (void*) SERCOM5_0_Handler,      /* 66 SERCOM5_0 */
+        .pfnSERCOM5_1_Handler   = (void*) SERCOM5_1_Handler,      /* 67 SERCOM5_1 */
+        .pfnSERCOM5_2_Handler   = (void*) SERCOM5_2_Handler,      /* 68 SERCOM5_2 */
+        .pfnSERCOM5_3_Handler   = (void*) SERCOM5_3_Handler,      /* 69 SERCOM5_3, SERCOM5_4, SERCOM5_5, SERCOM5_6 */
+#else
+        .pvReserved66           = (void*) (0UL),                  /* 66 Reserved */
+        .pvReserved67           = (void*) (0UL),                  /* 67 Reserved */
+        .pvReserved68           = (void*) (0UL),                  /* 68 Reserved */
+        .pvReserved69           = (void*) (0UL),                  /* 69 Reserved */
+#endif
+#ifdef ID_SERCOM6
+        .pfnSERCOM6_0_Handler   = (void*) SERCOM6_0_Handler,      /* 70 SERCOM6_0 */
+        .pfnSERCOM6_1_Handler   = (void*) SERCOM6_1_Handler,      /* 71 SERCOM6_1 */
+        .pfnSERCOM6_2_Handler   = (void*) SERCOM6_2_Handler,      /* 72 SERCOM6_2 */
+        .pfnSERCOM6_3_Handler   = (void*) SERCOM6_3_Handler,      /* 73 SERCOM6_3, SERCOM6_4, SERCOM6_5, SERCOM6_6 */
+#else
+        .pvReserved70           = (void*) (0UL),                  /* 70 Reserved */
+        .pvReserved71           = (void*) (0UL),                  /* 71 Reserved */
+        .pvReserved72           = (void*) (0UL),                  /* 72 Reserved */
+        .pvReserved73           = (void*) (0UL),                  /* 73 Reserved */
+#endif
+#ifdef ID_SERCOM7
+        .pfnSERCOM7_0_Handler   = (void*) SERCOM7_0_Handler,      /* 74 SERCOM7_0 */
+        .pfnSERCOM7_1_Handler   = (void*) SERCOM7_1_Handler,      /* 75 SERCOM7_1 */
+        .pfnSERCOM7_2_Handler   = (void*) SERCOM7_2_Handler,      /* 76 SERCOM7_2 */
+        .pfnSERCOM7_3_Handler   = (void*) SERCOM7_3_Handler,      /* 77 SERCOM7_3, SERCOM7_4, SERCOM7_5, SERCOM7_6 */
+#else
+        .pvReserved74           = (void*) (0UL),                  /* 74 Reserved */
+        .pvReserved75           = (void*) (0UL),                  /* 75 Reserved */
+        .pvReserved76           = (void*) (0UL),                  /* 76 Reserved */
+        .pvReserved77           = (void*) (0UL),                  /* 77 Reserved */
+#endif
+#ifdef ID_CAN0
+        .pfnCAN0_Handler        = (void*) CAN0_Handler,           /* 78 Control Area Network 0 */
+#else
+        .pvReserved78           = (void*) (0UL),                  /* 78 Reserved */
+#endif
+#ifdef ID_CAN1
+        .pfnCAN1_Handler        = (void*) CAN1_Handler,           /* 79 Control Area Network 1 */
+#else
+        .pvReserved79           = (void*) (0UL),                  /* 79 Reserved */
+#endif
+#ifdef ID_USB
+        .pfnUSB_0_Handler       = (void*) USB_0_Handler,          /* 80 USB_EORSM_DNRSM, USB_EORST_RST, USB_LPMSUSP_DDISC, USB_LPM_DCONN, USB_MSOF, USB_RAMACER, USB_RXSTP_TXSTP_0, USB_RXSTP_TXSTP_1, USB_RXSTP_TXSTP_2, USB_RXSTP_TXSTP_3, USB_RXSTP_TXSTP_4, USB_RXSTP_TXSTP_5, USB_RXSTP_TXSTP_6, USB_RXSTP_TXSTP_7, USB_STALL0_STALL_0, USB_STALL0_STALL_1, USB_STALL0_STALL_2, USB_STALL0_STALL_3, USB_STALL0_STALL_4, USB_STALL0_STALL_5, USB_STALL0_STALL_6, USB_STALL0_STALL_7, USB_STALL1_0, USB_STALL1_1, USB_STALL1_2, USB_STALL1_3, USB_STALL1_4, USB_STALL1_5, USB_STALL1_6, USB_STALL1_7, USB_SUSPEND, USB_TRFAIL0_TRFAIL_0, USB_TRFAIL0_TRFAIL_1, USB_TRFAIL0_TRFAIL_2, USB_TRFAIL0_TRFAIL_3, USB_TRFAIL0_TRFAIL_4, USB_TRFAIL0_TRFAIL_5, USB_TRFAIL0_TRFAIL_6, USB_TRFAIL0_TRFAIL_7, USB_TRFAIL1_PERR_0, USB_TRFAIL1_PERR_1, USB_TRFAIL1_PERR_2, USB_TRFAIL1_PERR_3, USB_TRFAIL1_PERR_4, USB_TRFAIL1_PERR_5, USB_TRFAIL1_PERR_6, USB_TRFAIL1_PERR_7, USB_UPRSM, USB_WAKEUP */
+        .pfnUSB_1_Handler       = (void*) USB_1_Handler,          /* 81 USB_SOF_HSOF */
+        .pfnUSB_2_Handler       = (void*) USB_2_Handler,          /* 82 USB_TRCPT0_0, USB_TRCPT0_1, USB_TRCPT0_2, USB_TRCPT0_3, USB_TRCPT0_4, USB_TRCPT0_5, USB_TRCPT0_6, USB_TRCPT0_7 */
+        .pfnUSB_3_Handler       = (void*) USB_3_Handler,          /* 83 USB_TRCPT1_0, USB_TRCPT1_1, USB_TRCPT1_2, USB_TRCPT1_3, USB_TRCPT1_4, USB_TRCPT1_5, USB_TRCPT1_6, USB_TRCPT1_7 */
+#else
+        .pvReserved80           = (void*) (0UL),                  /* 80 Reserved */
+        .pvReserved81           = (void*) (0UL),                  /* 81 Reserved */
+        .pvReserved82           = (void*) (0UL),                  /* 82 Reserved */
+        .pvReserved83           = (void*) (0UL),                  /* 83 Reserved */
+#endif
+#ifdef ID_GMAC
+        .pfnGMAC_Handler        = (void*) GMAC_Handler,           /* 84 Ethernet MAC */
+#else
+        .pvReserved84           = (void*) (0UL),                  /* 84 Reserved */
+#endif
+        .pfnTCC0_0_Handler      = (void*) TCC0_0_Handler,         /* 85 TCC0_CNT_A, TCC0_DFS_A, TCC0_ERR_A, TCC0_FAULT0_A, TCC0_FAULT1_A, TCC0_FAULTA_A, TCC0_FAULTB_A, TCC0_OVF, TCC0_TRG, TCC0_UFS_A */
+        .pfnTCC0_1_Handler      = (void*) TCC0_1_Handler,         /* 86 TCC0_MC_0 */
+        .pfnTCC0_2_Handler      = (void*) TCC0_2_Handler,         /* 87 TCC0_MC_1 */
+        .pfnTCC0_3_Handler      = (void*) TCC0_3_Handler,         /* 88 TCC0_MC_2 */
+        .pfnTCC0_4_Handler      = (void*) TCC0_4_Handler,         /* 89 TCC0_MC_3 */
+        .pfnTCC0_5_Handler      = (void*) TCC0_5_Handler,         /* 90 TCC0_MC_4 */
+        .pfnTCC0_6_Handler      = (void*) TCC0_6_Handler,         /* 91 TCC0_MC_5 */
+        .pfnTCC1_0_Handler      = (void*) TCC1_0_Handler,         /* 92 TCC1_CNT_A, TCC1_DFS_A, TCC1_ERR_A, TCC1_FAULT0_A, TCC1_FAULT1_A, TCC1_FAULTA_A, TCC1_FAULTB_A, TCC1_OVF, TCC1_TRG, TCC1_UFS_A */
+        .pfnTCC1_1_Handler      = (void*) TCC1_1_Handler,         /* 93 TCC1_MC_0 */
+        .pfnTCC1_2_Handler      = (void*) TCC1_2_Handler,         /* 94 TCC1_MC_1 */
+        .pfnTCC1_3_Handler      = (void*) TCC1_3_Handler,         /* 95 TCC1_MC_2 */
+        .pfnTCC1_4_Handler      = (void*) TCC1_4_Handler,         /* 96 TCC1_MC_3 */
+        .pfnTCC2_0_Handler      = (void*) TCC2_0_Handler,         /* 97 TCC2_CNT_A, TCC2_DFS_A, TCC2_ERR_A, TCC2_FAULT0_A, TCC2_FAULT1_A, TCC2_FAULTA_A, TCC2_FAULTB_A, TCC2_OVF, TCC2_TRG, TCC2_UFS_A */
+        .pfnTCC2_1_Handler      = (void*) TCC2_1_Handler,         /* 98 TCC2_MC_0 */
+        .pfnTCC2_2_Handler      = (void*) TCC2_2_Handler,         /* 99 TCC2_MC_1 */
+        .pfnTCC2_3_Handler      = (void*) TCC2_3_Handler,         /* 100 TCC2_MC_2 */
+#ifdef ID_TCC3
+        .pfnTCC3_0_Handler      = (void*) TCC3_0_Handler,         /* 101 TCC3_CNT_A, TCC3_DFS_A, TCC3_ERR_A, TCC3_FAULT0_A, TCC3_FAULT1_A, TCC3_FAULTA_A, TCC3_FAULTB_A, TCC3_OVF, TCC3_TRG, TCC3_UFS_A */
+        .pfnTCC3_1_Handler      = (void*) TCC3_1_Handler,         /* 102 TCC3_MC_0 */
+        .pfnTCC3_2_Handler      = (void*) TCC3_2_Handler,         /* 103 TCC3_MC_1 */
+#else
+        .pvReserved101          = (void*) (0UL),                  /* 101 Reserved */
+        .pvReserved102          = (void*) (0UL),                  /* 102 Reserved */
+        .pvReserved103          = (void*) (0UL),                  /* 103 Reserved */
+#endif
+#ifdef ID_TCC4
+        .pfnTCC4_0_Handler      = (void*) TCC4_0_Handler,         /* 104 TCC4_CNT_A, TCC4_DFS_A, TCC4_ERR_A, TCC4_FAULT0_A, TCC4_FAULT1_A, TCC4_FAULTA_A, TCC4_FAULTB_A, TCC4_OVF, TCC4_TRG, TCC4_UFS_A */
+        .pfnTCC4_1_Handler      = (void*) TCC4_1_Handler,         /* 105 TCC4_MC_0 */
+        .pfnTCC4_2_Handler      = (void*) TCC4_2_Handler,         /* 106 TCC4_MC_1 */
+#else
+        .pvReserved104          = (void*) (0UL),                  /* 104 Reserved */
+        .pvReserved105          = (void*) (0UL),                  /* 105 Reserved */
+        .pvReserved106          = (void*) (0UL),                  /* 106 Reserved */
+#endif
+        .pfnTC0_Handler         = (void*) TC0_Handler,            /* 107 Basic Timer Counter 0 */
+        .pfnTC1_Handler         = (void*) TC1_Handler,            /* 108 Basic Timer Counter 1 */
+        .pfnTC2_Handler         = (void*) TC2_Handler,            /* 109 Basic Timer Counter 2 */
+        .pfnTC3_Handler         = (void*) TC3_Handler,            /* 110 Basic Timer Counter 3 */
+#ifdef ID_TC4
+        .pfnTC4_Handler         = (void*) TC4_Handler,            /* 111 Basic Timer Counter 4 */
+#else
+        .pvReserved111          = (void*) (0UL),                  /* 111 Reserved */
+#endif
+#ifdef ID_TC5
+        .pfnTC5_Handler         = (void*) TC5_Handler,            /* 112 Basic Timer Counter 5 */
+#else
+        .pvReserved112          = (void*) (0UL),                  /* 112 Reserved */
+#endif
+#ifdef ID_TC6
+        .pfnTC6_Handler         = (void*) TC6_Handler,            /* 113 Basic Timer Counter 6 */
+#else
+        .pvReserved113          = (void*) (0UL),                  /* 113 Reserved */
+#endif
+#ifdef ID_TC7
+        .pfnTC7_Handler         = (void*) TC7_Handler,            /* 114 Basic Timer Counter 7 */
+#else
+        .pvReserved114          = (void*) (0UL),                  /* 114 Reserved */
+#endif
+        .pfnPDEC_0_Handler      = (void*) PDEC_0_Handler,         /* 115 PDEC_DIR_A, PDEC_ERR_A, PDEC_OVF, PDEC_VLC_A */
+        .pfnPDEC_1_Handler      = (void*) PDEC_1_Handler,         /* 116 PDEC_MC_0 */
+        .pfnPDEC_2_Handler      = (void*) PDEC_2_Handler,         /* 117 PDEC_MC_1 */
+        .pfnADC0_0_Handler      = (void*) ADC0_0_Handler,         /* 118 ADC0_OVERRUN, ADC0_WINMON */
+        .pfnADC0_1_Handler      = (void*) ADC0_1_Handler,         /* 119 ADC0_RESRDY */
+        .pfnADC1_0_Handler      = (void*) ADC1_0_Handler,         /* 120 ADC1_OVERRUN, ADC1_WINMON */
+        .pfnADC1_1_Handler      = (void*) ADC1_1_Handler,         /* 121 ADC1_RESRDY */
+        .pfnAC_Handler          = (void*) AC_Handler,             /* 122 Analog Comparators */
+        .pfnDAC_0_Handler       = (void*) DAC_0_Handler,          /* 123 DAC_OVERRUN_A_0, DAC_OVERRUN_A_1, DAC_UNDERRUN_A_0, DAC_UNDERRUN_A_1 */
+        .pfnDAC_1_Handler       = (void*) DAC_1_Handler,          /* 124 DAC_EMPTY_0 */
+        .pfnDAC_2_Handler       = (void*) DAC_2_Handler,          /* 125 DAC_EMPTY_1 */
+        .pfnDAC_3_Handler       = (void*) DAC_3_Handler,          /* 126 DAC_RESRDY_0 */
+        .pfnDAC_4_Handler       = (void*) DAC_4_Handler,          /* 127 DAC_RESRDY_1 */
+#ifdef ID_I2S
+        .pfnI2S_Handler         = (void*) I2S_Handler,            /* 128 Inter-IC Sound Interface */
+#else
+        .pvReserved128          = (void*) (0UL),                  /* 128 Reserved */
+#endif
+        .pfnPCC_Handler         = (void*) PCC_Handler,            /* 129 Parallel Capture Controller */
+        .pfnAES_Handler         = (void*) AES_Handler,            /* 130 Advanced Encryption Standard */
+        .pfnTRNG_Handler        = (void*) TRNG_Handler,           /* 131 True Random Generator */
+#ifdef ID_ICM
+        .pfnICM_Handler         = (void*) ICM_Handler,            /* 132 Integrity Check Monitor */
+#else
+        .pvReserved132          = (void*) (0UL),                  /* 132 Reserved */
+#endif
+#ifdef ID_PUKCC
+        .pfnPUKCC_Handler       = (void*) PUKCC_Handler,          /* 133 PUblic-Key Cryptography Controller */
+#else
+        .pvReserved133          = (void*) (0UL),                  /* 133 Reserved */
+#endif
+        .pfnQSPI_Handler        = (void*) QSPI_Handler,           /* 134 Quad SPI interface */
+#ifdef ID_SDHC0
+        .pfnSDHC0_Handler       = (void*) SDHC0_Handler,          /* 135 SD/MMC Host Controller 0 */
+#else
+        .pvReserved135          = (void*) (0UL),                  /* 135 Reserved */
+#endif
+#ifdef ID_SDHC1
+        .pfnSDHC1_Handler       = (void*) SDHC1_Handler           /* 136 SD/MMC Host Controller 1 */
+#else
+        .pvReserved136          = (void*) (0UL)                   /* 136 Reserved */
+#endif
+};
+
+/**
+ * \brief This is the code that gets called on processor reset.
+ * To initialize the device, and call the main() routine.
+ */
+void Reset_Handler(void)
+{
+        uint32_t *pSrc, *pDest;
+
+        /* 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 __FPU_USED
+        /* Enable FPU */
+        SCB->CPACR |=  (0xFu << 20);
+        __DSB();
+        __ISB();
+#endif
+
+        /* Initialize the C library */
+        __libc_init_array();
+
+        /* Branch to main function */
+        main();
+
+        /* Infinite loop */
+        while (1);
+}
+
+/**
+ * \brief Default interrupt handler for unused IRQs.
+ */
+void Dummy_Handler(void)
+{
+        while (1) {
+        }
+}
diff --git a/embedded/mkrouter-v06/mkrouter-v06/Device_Startup/system_samd51.c b/embedded/mkrouter-v06/mkrouter-v06/Device_Startup/system_samd51.c
new file mode 100644
index 0000000000000000000000000000000000000000..2df9920d50003b9db866e08fb232caf0e721145c
--- /dev/null
+++ b/embedded/mkrouter-v06/mkrouter-v06/Device_Startup/system_samd51.c
@@ -0,0 +1,64 @@
+/**
+ * \file
+ *
+ * \brief Low-level initialization functions called upon chip startup.
+ *
+ * Copyright (c) 2017 Microchip Technology Inc.
+ *
+ * \asf_license_start
+ *
+ * \page License
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the Licence at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * \asf_license_stop
+ *
+ */
+
+#include "samd51.h"
+
+/**
+ * Initial system clock frequency. The System RC Oscillator (RCSYS) provides
+ *  the source for the main clock at chip startup.
+ */
+#define __SYSTEM_CLOCK    (48000000)
+
+uint32_t SystemCoreClock = __SYSTEM_CLOCK;/*!< System Clock Frequency (Core Clock)*/
+
+/**
+ * Initialize the system
+ *
+ * @brief  Setup the microcontroller system.
+ *         Initialize the System and update the SystemCoreClock variable.
+ */
+void SystemInit(void)
+{
+	// Keep the default device state after reset
+	SystemCoreClock = __SYSTEM_CLOCK;
+	return;
+}
+
+/**
+ * Update SystemCoreClock variable
+ *
+ * @brief  Updates the SystemCoreClock with current core Clock
+ *         retrieved from cpu registers.
+ */
+void SystemCoreClockUpdate(void)
+{
+	// Not implemented
+	SystemCoreClock = __SYSTEM_CLOCK;
+	return;
+}
diff --git a/embedded/mkrouter-v06/mkrouter-v06/board_definitions.h b/embedded/mkrouter-v06/mkrouter-v06/board_definitions.h
new file mode 100644
index 0000000000000000000000000000000000000000..f17f687a6eb349a52b2b5b4ce82b6e1500eff1f7
--- /dev/null
+++ b/embedded/mkrouter-v06/mkrouter-v06/board_definitions.h
@@ -0,0 +1,84 @@
+/*
+  Copyright (c) 2015 Arduino LLC.  All right reserved.
+  Copyright (c) 2015 Atmel Corporation/Thibaut VIARD.  All right reserved.
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  This library 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 Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+
+#ifndef _BOARD_DEFINITIONS_H_
+#define _BOARD_DEFINITIONS_H_
+/*
+ * USB device definitions
+ */
+#define STRING_PRODUCT "Metro M4"
+#define USB_VID_HIGH   0x23
+#define USB_VID_LOW    0x9A
+#define USB_PID_HIGH   0x00
+#define USB_PID_LOW    0x20
+
+
+/*
+ * If BOOT_DOUBLE_TAP_ADDRESS is defined the bootloader is started by
+ * quickly tapping two times on the reset button.
+ * BOOT_DOUBLE_TAP_ADDRESS must point to a free SRAM cell that must not
+ * be touched from the loaded application.
+ */
+#define BOOT_DOUBLE_TAP_ADDRESS           (HSRAM_ADDR + HSRAM_SIZE - 4)
+#define BOOT_DOUBLE_TAP_DATA              (*((volatile uint32_t *)BOOT_DOUBLE_TAP_ADDRESS))
+
+/*
+ * If BOOT_LOAD_PIN is defined the bootloader is started if the selected
+ * pin is tied LOW.
+ */
+//#define BOOT_LOAD_PIN                     PIN_PA21 // Pin 7
+//#define BOOT_LOAD_PIN                     PIN_PA15 // Pin 5
+
+#define GPIO(port, pin) ((((port)&0x7u) << 5) + ((pin)&0x1Fu))
+
+#define BOOK_USART_MASK					  APBAMASK
+#define BOOT_USART_MODULE                 SERCOM0
+#define BOOT_USART_BUS_CLOCK_INDEX        MCLK_APBAMASK_SERCOM0
+#define BOOT_GCLK_ID_CORE				  SERCOM0_GCLK_ID_CORE
+#define BOOT_GCLK_ID_SLOW				  SERCOM0_GCLK_ID_SLOW
+#define BOOT_USART_PAD_SETTINGS           UART_RX_PAD3_TX_PAD2
+#define BOOT_USART_PAD3                   PINMUX_UNUSED
+#define BOOT_USART_PAD2                   PINMUX_UNUSED
+
+#define BOOT_USART_PAD1                   PINMUX_PA10C_SERCOM0_PAD2
+#define BOOT_USART_PAD0                   PINMUX_PA11C_SERCOM0_PAD3
+
+/* Master clock frequency */
+#define CPU_FREQUENCY                     (120000000ul)
+#define VARIANT_MCK                       CPU_FREQUENCY
+
+/* Frequency of the board main oscillator */
+#define VARIANT_MAINOSC                   (32768ul)
+
+/* Calibration values for DFLL48 pll */
+#define NVM_SW_CALIB_DFLL48M_COARSE_VAL   (58)
+#define NVM_SW_CALIB_DFLL48M_FINE_VAL     (64)
+
+#define BOARD_LED_PORT                    (0)
+#define BOARD_LED_PIN                     (21)
+
+#define BOARD_LEDRX_PORT                  (1)
+#define BOARD_LEDRX_PIN                   (6)
+
+#define BOARD_LEDTX_PORT                  (0)
+#define BOARD_LEDTX_PIN                   (27)
+
+#define BOOT_PIN_MASK (1U << (BOOT_LOAD_PIN & 0x1f))
+
+#endif // _BOARD_DEFINITIONS_H_
diff --git a/embedded/mkrouter-v06/mkrouter-v06/board_driver_serial.c b/embedded/mkrouter-v06/mkrouter-v06/board_driver_serial.c
new file mode 100644
index 0000000000000000000000000000000000000000..c474c5b75a3d826f4b8f40ef4142ab856a22af46
--- /dev/null
+++ b/embedded/mkrouter-v06/mkrouter-v06/board_driver_serial.c
@@ -0,0 +1,104 @@
+ /*
+  Copyright (c) 2015 Arduino LLC.  All right reserved.
+  Copyright (c) 2015 Atmel Corporation/Thibaut VIARD.  All right reserved.
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  This library 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 Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+
+#include "board_driver_serial.h"
+
+bool uart_drv_error_flag = false;
+
+void uart_basic_init(Sercom *sercom, uint16_t baud_val, enum uart_pad_settings pad_conf)
+{
+	/* Wait for synchronization */
+	while(sercom->USART.SYNCBUSY.bit.ENABLE);
+	/* Disable the SERCOM UART module */
+	sercom->USART.CTRLA.bit.ENABLE = 0;
+	/* Wait for synchronization */
+	while(sercom->USART.SYNCBUSY.bit.SWRST);
+	/* Perform a software reset */
+	sercom->USART.CTRLA.bit.SWRST = 1;
+	/* Wait for synchronization */
+	while(sercom->USART.CTRLA.bit.SWRST);
+	/* Wait for synchronization */
+	while(sercom->USART.SYNCBUSY.bit.SWRST || sercom->USART.SYNCBUSY.bit.ENABLE);
+	/* Update the UART pad settings, mode and data order settings */
+	sercom->USART.CTRLA.reg = pad_conf | SERCOM_USART_CTRLA_MODE(1) | SERCOM_USART_CTRLA_DORD;
+	/* Wait for synchronization */
+	while(sercom->USART.SYNCBUSY.bit.CTRLB);
+	/* Enable transmit and receive and set data size to 8 bits */
+	sercom->USART.CTRLB.reg = SERCOM_USART_CTRLB_RXEN | SERCOM_USART_CTRLB_TXEN | SERCOM_USART_CTRLB_CHSIZE(0);
+	/* Load the baud value */
+	sercom->USART.BAUD.reg = baud_val;
+	///* Wait for synchronization */
+	while(sercom->USART.SYNCBUSY.bit.ENABLE);
+	/* Enable SERCOM UART */
+	sercom->USART.CTRLA.bit.ENABLE = 1;
+}
+
+void uart_disable(Sercom *sercom)
+{
+	/* Wait for synchronization */
+	while(sercom->USART.SYNCBUSY.bit.ENABLE);
+	/* Disable SERCOM UART */
+	sercom->USART.CTRLA.bit.ENABLE = 0;
+}
+
+void uart_write_byte(Sercom *sercom, uint8_t data)
+{
+	/* Wait for Data Register Empty flag */
+	while(!sercom->USART.INTFLAG.bit.DRE);
+	/* Write the data to DATA register */
+	sercom->USART.DATA.reg = (uint16_t)data;
+}
+
+uint8_t uart_read_byte(Sercom *sercom)
+{
+	/* Wait for Receive Complete flag */
+	while(!sercom->USART.INTFLAG.bit.RXC);
+	/* Check for errors */
+	if (sercom->USART.STATUS.bit.PERR || sercom->USART.STATUS.bit.FERR || sercom->USART.STATUS.bit.BUFOVF)
+		/* Set the error flag */
+		uart_drv_error_flag = true;
+	/* Return the read data */
+	return((uint8_t)sercom->USART.DATA.reg);
+}
+
+void uart_write_buffer_polled(Sercom *sercom, uint8_t *ptr, uint16_t length)
+{
+	/* Do the following for specified length */
+	do {
+		/* Wait for Data Register Empty flag */
+		while(!sercom->USART.INTFLAG.bit.DRE);
+		/* Send data from the buffer */
+		sercom->USART.DATA.reg = (uint16_t)*ptr++;
+	} while (length--);
+}
+
+void uart_read_buffer_polled(Sercom *sercom, uint8_t *ptr, uint16_t length)
+{
+	/* Do the following for specified length */
+	do {
+		/* Wait for Receive Complete flag */
+		while(!sercom->USART.INTFLAG.bit.RXC);
+		/* Check for errors */
+		if (sercom->USART.STATUS.bit.PERR || sercom->USART.STATUS.bit.FERR || sercom->USART.STATUS.bit.BUFOVF)
+			/* Set the error flag */
+			uart_drv_error_flag = true;
+		/* Store the read data to the buffer */
+		*ptr++ = (uint8_t)sercom->USART.DATA.reg;
+	} while (length--);
+}
diff --git a/embedded/mkrouter-v06/mkrouter-v06/board_driver_serial.h b/embedded/mkrouter-v06/mkrouter-v06/board_driver_serial.h
new file mode 100644
index 0000000000000000000000000000000000000000..809f7ec0146c5a8a64b572a58edc30a38086fbea
--- /dev/null
+++ b/embedded/mkrouter-v06/mkrouter-v06/board_driver_serial.h
@@ -0,0 +1,89 @@
+/*
+  Copyright (c) 2015 Arduino LLC.  All right reserved.
+  Copyright (c) 2015 Atmel Corporation/Thibaut VIARD.  All right reserved.
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  This library 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 Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+
+#ifndef UART_DRIVER_H
+#define UART_DRIVER_H
+
+#include <stdio.h>
+#include <stdbool.h>
+#include <sam.h>
+
+#define PINMUX_UNUSED          0xFFFFFFFF
+
+/* SERCOM UART available pad settings */
+enum uart_pad_settings {
+	UART_RX_PAD0_TX_PAD2 = SERCOM_USART_CTRLA_RXPO(0) | SERCOM_USART_CTRLA_TXPO(1),
+	UART_RX_PAD1_TX_PAD2 = SERCOM_USART_CTRLA_RXPO(1) | SERCOM_USART_CTRLA_TXPO(1),
+	UART_RX_PAD2_TX_PAD0 = SERCOM_USART_CTRLA_RXPO(2),
+	UART_RX_PAD3_TX_PAD0 = SERCOM_USART_CTRLA_RXPO(3),
+	UART_RX_PAD1_TX_PAD0 = SERCOM_USART_CTRLA_RXPO(1),
+	UART_RX_PAD3_TX_PAD2 = SERCOM_USART_CTRLA_RXPO(3) | SERCOM_USART_CTRLA_TXPO(1),
+};
+
+/**
+ * \brief Initializes the UART
+ *
+ * \param Pointer to SERCOM instance
+ * \param Baud value corresponding to the desired baudrate
+ * \param SERCOM pad settings
+ */
+void uart_basic_init(Sercom *sercom, uint16_t baud_val, enum uart_pad_settings pad_conf);
+
+/**
+ * \brief Disables UART interface
+ *
+ * \param Pointer to SERCOM instance
+ */
+void uart_disable(Sercom *sercom);
+
+/**
+ * \brief Sends a single byte through UART interface
+ *
+ * \param Pointer to SERCOM instance
+ * \param Data to send
+ */
+void uart_write_byte(Sercom *sercom, uint8_t data);
+
+/**
+ * \brief Reads a single character from UART interface
+ *
+ * \param Pointer to SERCOM instance
+ * \return Data byte read
+ */
+uint8_t uart_read_byte(Sercom *sercom);
+
+/**
+ * \brief Sends buffer on UART interface
+ *
+ * \param Pointer to SERCOM instance
+ * \param Pointer to data to send
+ * \param Number of bytes to send
+ */
+void uart_write_buffer_polled(Sercom *sercom, uint8_t *ptr, uint16_t length);
+
+/**
+ * \brief Reads data on UART interface
+ *
+ * \param Pointer to SERCOM instance
+ * \param Pointer to store read data
+ * \param Number of bytes to read
+ */
+void uart_read_buffer_polled(Sercom *sercom, uint8_t *ptr, uint16_t length);
+
+#endif
diff --git a/embedded/mkrouter-v06/mkrouter-v06/board_driver_usb.c b/embedded/mkrouter-v06/mkrouter-v06/board_driver_usb.c
new file mode 100644
index 0000000000000000000000000000000000000000..1e38dce8b55550f2f73981691c0f0dfb0e873391
--- /dev/null
+++ b/embedded/mkrouter-v06/mkrouter-v06/board_driver_usb.c
@@ -0,0 +1,359 @@
+/*
+  Copyright (c) 2015 Arduino LLC.  All right reserved.
+  Copyright (c) 2015 Atmel Corporation/Thibaut VIARD.  All right reserved.
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  This library 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 Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+
+#include <string.h>
+#include "board_driver_usb.h"
+#include "sam_ba_usb.h"
+#include "sam_ba_cdc.h"
+
+#define NVM_USB_PAD_TRANSN_POS 32
+#define NVM_USB_PAD_TRANSN_SIZE 5
+#define NVM_USB_PAD_TRANSP_POS 37
+#define NVM_USB_PAD_TRANSP_SIZE 5
+#define NVM_USB_PAD_TRIM_POS 42
+#define NVM_USB_PAD_TRIM_SIZE 3
+
+__attribute__((__aligned__(4))) UsbDeviceDescriptor usb_endpoint_table[MAX_EP]; // Initialized to zero in USB_Init
+__attribute__((__aligned__(4))) uint8_t udd_ep_out_cache_buffer[2][64]; //1 for CTRL, 1 for BULK
+__attribute__((__aligned__(4))) uint8_t udd_ep_in_cache_buffer[2][64]; //1 for CTRL, 1 for BULK
+
+static volatile bool read_job = false;
+
+/*----------------------------------------------------------------------------
+ * \brief
+ */
+P_USB_CDC USB_Open(P_USB_CDC pCdc, Usb *pUsb)
+{
+  pCdc->pUsb = pUsb;
+  pCdc->currentConfiguration = 0;
+  pCdc->currentConnection    = 0;
+  pCdc->IsConfigured = USB_IsConfigured;
+//  pCdc->Write        = USB_Write;
+//  pCdc->Read         = USB_Read;
+
+  pCdc->pUsb->HOST.CTRLA.bit.ENABLE = true;
+  
+  while( pCdc->pUsb->HOST.SYNCBUSY.reg & USB_SYNCBUSY_ENABLE ); //wait for sync
+
+  return pCdc;
+}
+
+
+/**
+ * \brief Load USB calibration value from NVM
+ */
+static void USB_load_calib(void)
+{
+	Usb *    hw = USB;
+	uint32_t pad_transn
+	    = (*((uint32_t *)(NVMCTRL_SW0) + (NVM_USB_PAD_TRANSN_POS / 32)) >> (NVM_USB_PAD_TRANSN_POS % 32))
+	      & ((1 << NVM_USB_PAD_TRANSN_SIZE) - 1);
+	uint32_t pad_transp
+	    = (*((uint32_t *)(NVMCTRL_SW0) + (NVM_USB_PAD_TRANSP_POS / 32)) >> (NVM_USB_PAD_TRANSP_POS % 32))
+	      & ((1 << NVM_USB_PAD_TRANSP_SIZE) - 1);
+	uint32_t pad_trim = (*((uint32_t *)(NVMCTRL_SW0) + (NVM_USB_PAD_TRIM_POS / 32)) >> (NVM_USB_PAD_TRIM_POS % 32))
+	                    & ((1 << NVM_USB_PAD_TRIM_SIZE) - 1);
+	if (pad_transn == 0 || pad_transn == 0x1F) {
+		pad_transn = 9;
+	}
+	if (pad_transp == 0 || pad_transp == 0x1F) {
+		pad_transp = 25;
+	}
+	if (pad_trim == 0 || pad_trim == 0x7) {
+		pad_trim = 6;
+	}
+
+	hw->DEVICE.PADCAL.reg = USB_PADCAL_TRANSN(pad_transn) | USB_PADCAL_TRANSP(pad_transp) | USB_PADCAL_TRIM(pad_trim);
+
+	hw->DEVICE.QOSCTRL.bit.CQOS = 3;
+	hw->DEVICE.QOSCTRL.bit.DQOS = 3;
+}
+
+/*----------------------------------------------------------------------------
+ * \brief Initializes USB
+ */
+void USB_Init(void)
+{
+  uint32_t pad_transn, pad_transp, pad_trim;
+
+  /* Enable USB clock */
+  MCLK->APBBMASK.bit.USB_ = 1;
+
+  /* Set up the USB DP/DN pins */
+  PORT->Group[0].PINCFG[PIN_PA24H_USB_DM].bit.PMUXEN = 1;
+  PORT->Group[0].PMUX[PIN_PA24H_USB_DM/2].reg &= ~(0xF << (4 * (PIN_PA24H_USB_DM & 0x01u)));
+  PORT->Group[0].PMUX[PIN_PA24H_USB_DM/2].reg |= MUX_PA24H_USB_DM << (4 * (PIN_PA24H_USB_DM & 0x01u));
+  PORT->Group[0].PINCFG[PIN_PA25H_USB_DP].bit.PMUXEN = 1;
+  PORT->Group[0].PMUX[PIN_PA25H_USB_DP/2].reg &= ~(0xF << (4 * (PIN_PA25H_USB_DP & 0x01u)));
+  PORT->Group[0].PMUX[PIN_PA25H_USB_DP/2].reg |= MUX_PA25H_USB_DP << (4 * (PIN_PA25H_USB_DP & 0x01u));
+
+  /* ----------------------------------------------------------------------------------------------
+   * Put Generic Clock Generator 0 as source for Generic Clock Multiplexer 6 (USB reference)
+   *
+	*/
+  GCLK->PCHCTRL[USB_GCLK_ID].reg = GCLK_PCHCTRL_GEN_GCLK1_Val | (1 << GCLK_PCHCTRL_CHEN_Pos);
+  MCLK->APBBMASK.reg |= MCLK_APBBMASK_USB;
+  while(GCLK->SYNCBUSY.bit.GENCTRL1)
+  {
+    /* Wait for synchronization */
+  }
+
+  /* Reset */
+  USB->DEVICE.CTRLA.bit.SWRST = 1;
+  while (USB->DEVICE.SYNCBUSY.bit.SWRST)
+  {
+    /* Sync wait */
+  }
+
+  USB_load_calib();
+
+  /* Set the configuration */
+  /* Set mode to Device mode */
+  USB->HOST.CTRLA.bit.MODE = 0;
+  /* Enable Run in Standby */
+  USB->HOST.CTRLA.bit.RUNSTDBY = true;
+  /* Set the descriptor address */
+  USB->HOST.DESCADD.reg = (uint32_t)(&usb_endpoint_table[0]);
+  /* Set speed configuration to Full speed */
+  USB->DEVICE.CTRLB.bit.SPDCONF = USB_DEVICE_CTRLB_SPDCONF_FS_Val;
+  /* Attach to the USB host */
+  USB->DEVICE.CTRLB.reg &= ~USB_DEVICE_CTRLB_DETACH;
+
+  /* Initialize endpoint table RAM location to a known value 0 */
+  memset((uint8_t *)(&usb_endpoint_table[0]), 0, sizeof(usb_endpoint_table));
+}
+
+uint32_t USB_Write(Usb *pUsb, const char *pData, uint32_t length, uint8_t ep_num)
+{
+  uint32_t data_address;
+  uint8_t buf_index;
+
+  /* Set buffer index */
+  buf_index = (ep_num == 0) ? 0 : 1;
+
+  /* Check for requirement for multi-packet or auto zlp */
+  if (length >= (1 << (usb_endpoint_table[ep_num].DeviceDescBank[1].PCKSIZE.bit.SIZE + 3)))
+  {
+    /* Update the EP data address */
+    data_address = (uint32_t) pData;
+    /* Enable auto zlp */
+    usb_endpoint_table[ep_num].DeviceDescBank[1].PCKSIZE.bit.AUTO_ZLP = true;
+  }
+  else
+  {
+    /* Copy to local buffer */
+    memcpy(udd_ep_in_cache_buffer[buf_index], pData, length);
+    /* Update the EP data address */
+    data_address = (uint32_t) &udd_ep_in_cache_buffer[buf_index];
+  }
+
+  /* Set the buffer address for ep data */
+  usb_endpoint_table[ep_num].DeviceDescBank[1].ADDR.reg = data_address;
+  /* Set the byte count as zero */
+  usb_endpoint_table[ep_num].DeviceDescBank[1].PCKSIZE.bit.BYTE_COUNT = length;
+  /* Set the multi packet size as zero for multi-packet transfers where length > ep size */
+  usb_endpoint_table[ep_num].DeviceDescBank[1].PCKSIZE.bit.MULTI_PACKET_SIZE = 0;
+  /* Clear the transfer complete flag  */
+  pUsb->DEVICE.DeviceEndpoint[ep_num].EPINTFLAG.reg = USB_DEVICE_EPINTFLAG_TRCPT1;
+  /* Set the bank as ready */
+  pUsb->DEVICE.DeviceEndpoint[ep_num].EPSTATUSSET.bit.BK1RDY = true;
+
+  /* Wait for transfer to complete */
+  while ( (pUsb->DEVICE.DeviceEndpoint[ep_num].EPINTFLAG.bit.TRCPT1) == 0 );
+
+  return length;
+}
+
+/*----------------------------------------------------------------------------
+ * \brief Read available data from Endpoint OUT
+ */
+uint32_t USB_Read(Usb *pUsb, char *pData, uint32_t length)
+{
+  uint32_t packetSize = 0;
+
+  if (!read_job)
+  {
+    /* Set the buffer address for ep data */
+    usb_endpoint_table[USB_EP_OUT].DeviceDescBank[0].ADDR.reg = (uint32_t)&udd_ep_out_cache_buffer[USB_EP_OUT-1];
+    /* Set the byte count as zero */
+    usb_endpoint_table[USB_EP_OUT].DeviceDescBank[0].PCKSIZE.bit.BYTE_COUNT = 0;
+    /* Set the byte count as zero */
+    usb_endpoint_table[USB_EP_OUT].DeviceDescBank[0].PCKSIZE.bit.MULTI_PACKET_SIZE = 0;
+    /* Start the reception by clearing the bank 0 ready bit */
+    pUsb->DEVICE.DeviceEndpoint[USB_EP_OUT].EPSTATUSCLR.bit.BK0RDY = true;
+    /* set the user flag */
+    read_job = true;
+  }
+
+  /* Check for Transfer Complete 0 flag */
+  if ( pUsb->DEVICE.DeviceEndpoint[USB_EP_OUT].EPINTFLAG.bit.TRCPT0 )
+  {
+    /* Set packet size */
+    packetSize = SAM_BA_MIN(usb_endpoint_table[USB_EP_OUT].DeviceDescBank[0].PCKSIZE.bit.BYTE_COUNT, length);
+    /* Copy read data to user buffer */
+    memcpy(pData, udd_ep_out_cache_buffer[USB_EP_OUT-1], packetSize);
+    /* Clear the Transfer Complete 0 flag */
+    pUsb->DEVICE.DeviceEndpoint[USB_EP_OUT].EPINTFLAG.reg = USB_DEVICE_EPINTFLAG_TRCPT0;
+    /* Clear the user flag */
+    read_job = false;
+  }
+
+  return packetSize;
+}
+
+uint32_t USB_Read_blocking(Usb *pUsb, char *pData, uint32_t length)
+{
+  if (read_job)
+  {
+    /* Stop the reception by setting the bank 0 ready bit */
+    pUsb->DEVICE.DeviceEndpoint[USB_EP_OUT].EPSTATUSSET.bit.BK0RDY = true;
+    /* Clear the user flag */
+    read_job = false;
+  }
+
+  /* Set the buffer address for ep data */
+  usb_endpoint_table[USB_EP_OUT].DeviceDescBank[0].ADDR.reg = ((uint32_t)pData);
+  /* Set the byte count as zero */
+  usb_endpoint_table[USB_EP_OUT].DeviceDescBank[0].PCKSIZE.bit.BYTE_COUNT = 0;
+  /* Set the multi packet size as zero for multi-packet transfers where length > ep size */
+  usb_endpoint_table[USB_EP_OUT].DeviceDescBank[0].PCKSIZE.bit.MULTI_PACKET_SIZE = length;
+  /* Clear the bank 0 ready flag */
+  pUsb->DEVICE.DeviceEndpoint[USB_EP_OUT].EPSTATUSCLR.bit.BK0RDY = true;
+  /* Wait for transfer to complete */
+  while (!( pUsb->DEVICE.DeviceEndpoint[USB_EP_OUT].EPINTFLAG.bit.TRCPT0 ));
+  /* Clear Transfer complete 0 flag */
+  pUsb->DEVICE.DeviceEndpoint[USB_EP_OUT].EPINTFLAG.reg = USB_DEVICE_EPINTFLAG_TRCPT0;
+
+  return length;
+}
+
+/*----------------------------------------------------------------------------
+ * \brief Test if the device is configured and handle enumeration
+ */
+uint8_t USB_IsConfigured(P_USB_CDC pCdc)
+{
+  Usb *pUsb = pCdc->pUsb;
+
+  /* Check for End of Reset flag */
+  if (pUsb->DEVICE.INTFLAG.reg & USB_DEVICE_INTFLAG_EORST)
+  {
+    /* Clear the flag */
+    pUsb->DEVICE.INTFLAG.reg = USB_DEVICE_INTFLAG_EORST;
+    /* Set Device address as 0 */
+    pUsb->DEVICE.DADD.reg = USB_DEVICE_DADD_ADDEN | 0;
+    /* Configure endpoint 0 */
+    /* Configure Endpoint 0 for Control IN and Control OUT */
+    pUsb->DEVICE.DeviceEndpoint[0].EPCFG.reg = USB_DEVICE_EPCFG_EPTYPE0(1) | USB_DEVICE_EPCFG_EPTYPE1(1);
+    pUsb->DEVICE.DeviceEndpoint[0].EPSTATUSSET.reg = USB_DEVICE_EPSTATUSSET_BK0RDY;
+    pUsb->DEVICE.DeviceEndpoint[0].EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_BK1RDY;
+    /* Configure control OUT Packet size to 64 bytes */
+    usb_endpoint_table[0].DeviceDescBank[0].PCKSIZE.bit.SIZE = 3;
+    /* Configure control IN Packet size to 64 bytes */
+    usb_endpoint_table[0].DeviceDescBank[1].PCKSIZE.bit.SIZE = 3;
+    /* Configure the data buffer address for control OUT */
+    usb_endpoint_table[0].DeviceDescBank[0].ADDR.reg = (uint32_t)&udd_ep_out_cache_buffer[0];
+    /* Configure the data buffer address for control IN */
+    usb_endpoint_table[0].DeviceDescBank[1].ADDR.reg = (uint32_t)&udd_ep_in_cache_buffer[0];
+    /* Set Multipacket size to 8 for control OUT and byte count to 0*/
+    usb_endpoint_table[0].DeviceDescBank[0].PCKSIZE.bit.MULTI_PACKET_SIZE = 8;
+    usb_endpoint_table[0].DeviceDescBank[0].PCKSIZE.bit.BYTE_COUNT = 0;
+    pUsb->DEVICE.DeviceEndpoint[0].EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_BK0RDY;
+
+    // Reset current configuration value to 0
+    pCdc->currentConfiguration = 0;
+  }
+  else
+  {
+    if (pUsb->DEVICE.DeviceEndpoint[0].EPINTFLAG.reg & USB_DEVICE_EPINTFLAG_RXSTP)
+    {
+      sam_ba_usb_CDC_Enumerate(pCdc);
+    }
+  }
+
+  return pCdc->currentConfiguration;
+}
+
+/*----------------------------------------------------------------------------
+ * \brief Stall the control endpoint
+ */
+void USB_SendStall(Usb *pUsb, bool direction_in)
+{
+  /* Check the direction */
+  if (direction_in)
+  {
+    /* Set STALL request on IN direction */
+    pUsb->DEVICE.DeviceEndpoint[0].EPSTATUSSET.bit.STALLRQ1 = 1;
+  }
+  else
+  {
+    /* Set STALL request on OUT direction */
+    pUsb->DEVICE.DeviceEndpoint[0].EPSTATUSSET.bit.STALLRQ0 = 1;
+  }
+}
+
+/*----------------------------------------------------------------------------
+ * \brief Send zero length packet through the control endpoint
+ */
+void USB_SendZlp(Usb *pUsb)
+{
+  /* Set the byte count as zero */
+  usb_endpoint_table[0].DeviceDescBank[1].PCKSIZE.bit.BYTE_COUNT = 0;
+  /* Clear the transfer complete flag  */
+  pUsb->DEVICE.DeviceEndpoint[0].EPINTFLAG.reg = USB_DEVICE_EPINTFLAG_TRCPT1;
+  /* Set the bank as ready */
+  pUsb->DEVICE.DeviceEndpoint[0].EPSTATUSSET.bit.BK1RDY = true;
+  /* Wait for transfer to complete */
+  while (!( pUsb->DEVICE.DeviceEndpoint[0].EPINTFLAG.bit.TRCPT1 ));
+}
+
+/*----------------------------------------------------------------------------
+ * \brief Set USB device address obtained from host
+ */
+void USB_SetAddress(Usb *pUsb, uint16_t wValue)
+{
+  pUsb->DEVICE.DADD.reg = USB_DEVICE_DADD_ADDEN | wValue;
+}
+
+/*----------------------------------------------------------------------------
+ * \brief Configure USB device
+ */
+void USB_Configure(Usb *pUsb)
+{
+  /* Configure BULK OUT endpoint for CDC Data interface*/
+  pUsb->DEVICE.DeviceEndpoint[USB_EP_OUT].EPCFG.reg = USB_DEVICE_EPCFG_EPTYPE0(3);
+  /* Set maximum packet size as 64 bytes */
+  usb_endpoint_table[USB_EP_OUT].DeviceDescBank[0].PCKSIZE.bit.SIZE = 3;
+  pUsb->DEVICE.DeviceEndpoint[USB_EP_OUT].EPSTATUSSET.reg = USB_DEVICE_EPSTATUSSET_BK0RDY;
+  /* Configure the data buffer */
+  usb_endpoint_table[USB_EP_OUT].DeviceDescBank[0].ADDR.reg = (uint32_t)&udd_ep_out_cache_buffer[1];
+
+  /* Configure BULK IN endpoint for CDC Data interface */
+  pUsb->DEVICE.DeviceEndpoint[USB_EP_IN].EPCFG.reg = USB_DEVICE_EPCFG_EPTYPE1(3);
+  /* Set maximum packet size as 64 bytes */
+  usb_endpoint_table[USB_EP_IN].DeviceDescBank[1].PCKSIZE.bit.SIZE = 3;
+  pUsb->DEVICE.DeviceEndpoint[USB_EP_IN].EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_BK1RDY;
+  /* Configure the data buffer */
+  usb_endpoint_table[USB_EP_IN].DeviceDescBank[1].ADDR.reg = (uint32_t)&udd_ep_in_cache_buffer[1];
+
+  /* Configure INTERRUPT IN endpoint for CDC COMM interface*/
+  pUsb->DEVICE.DeviceEndpoint[USB_EP_COMM].EPCFG.reg = USB_DEVICE_EPCFG_EPTYPE1(4);
+  /* Set maximum packet size as 64 bytes */
+  usb_endpoint_table[USB_EP_COMM].DeviceDescBank[1].PCKSIZE.bit.SIZE = 0;
+  pUsb->DEVICE.DeviceEndpoint[USB_EP_COMM].EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_BK1RDY;
+}
diff --git a/embedded/mkrouter-v06/mkrouter-v06/board_driver_usb.h b/embedded/mkrouter-v06/mkrouter-v06/board_driver_usb.h
new file mode 100644
index 0000000000000000000000000000000000000000..2ee2022fd22a1f22339c9aa00ca4e0f5d1797d19
--- /dev/null
+++ b/embedded/mkrouter-v06/mkrouter-v06/board_driver_usb.h
@@ -0,0 +1,45 @@
+/*
+  Copyright (c) 2015 Arduino LLC.  All right reserved.
+  Copyright (c) 2015 Atmel Corporation/Thibaut VIARD.  All right reserved.
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  This library 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 Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+
+#ifndef _DRIVER_USB_H_
+#define _DRIVER_USB_H_
+
+#include "sam_ba_cdc.h"
+
+extern UsbDeviceDescriptor usb_endpoint_table[MAX_EP];
+extern uint8_t udd_ep_out_cache_buffer[2][64]; //1 for CTRL, 1 for BULK
+extern uint8_t udd_ep_in_cache_buffer[2][64]; //1 for CTRL, 1 for BULK
+
+P_USB_CDC USB_Open(P_USB_CDC pCdc, Usb *pUsb);
+
+void USB_Init(void);
+
+uint32_t USB_Write(Usb *pUsb, const char *pData, uint32_t length, uint8_t ep_num);
+uint32_t USB_Read(Usb *pUsb, char *pData, uint32_t length);
+uint32_t USB_Read_blocking(Usb *pUsb, char *pData, uint32_t length);
+
+uint8_t USB_IsConfigured(P_USB_CDC pCdc);
+
+void USB_SendStall(Usb *pUsb, bool direction_in);
+void USB_SendZlp(Usb *pUsb);
+
+void USB_SetAddress(Usb *pUsb, uint16_t wValue);
+void USB_Configure(Usb *pUsb);
+
+#endif // _BOARD_DRIVER_USB_H_
diff --git a/embedded/mkrouter-v06/mkrouter-v06/clock_init.c b/embedded/mkrouter-v06/mkrouter-v06/clock_init.c
new file mode 100644
index 0000000000000000000000000000000000000000..61736dd9fe96961972dc4e98e67cc9a8c1d916de
--- /dev/null
+++ b/embedded/mkrouter-v06/mkrouter-v06/clock_init.c
@@ -0,0 +1,129 @@
+
+#include <sam.h>
+#include "board_definitions.h"
+
+void clock_init(void)
+{
+	
+	/* Set 1 Flash Wait State for 48MHz */
+	NVMCTRL->CTRLA.reg |= NVMCTRL_CTRLA_RWS(0);
+
+	/* ----------------------------------------------------------------------------------------------
+	* 1) Enable XOSC32K clock (External on-board 32.768Hz oscillator)
+	*/
+	OSC32KCTRL->OSCULP32K.reg = OSC32KCTRL_OSCULP32K_EN32K;
+	/*
+	while( (OSC32KCTRL->STATUS.reg & OSC32KCTRL_STATUS_XOSC32KRDY) == 0 ){
+	// wait ready
+	}
+	*/
+	
+	OSC32KCTRL->RTCCTRL.bit.RTCSEL = OSC32KCTRL_RTCCTRL_RTCSEL_ULP1K;
+
+
+	/* Software reset the module to ensure it is re-initialized correctly */
+	/* Note: Due to synchronization, there is a delay from writing CTRL.SWRST until the reset is complete.
+	* CTRL.SWRST and STATUS.SYNCBUSY will both be cleared when the reset is complete
+	*/
+	GCLK->CTRLA.bit.SWRST = 1;
+	while ( GCLK->SYNCBUSY.reg & GCLK_SYNCBUSY_SWRST ){
+		/* wait for reset to complete */
+	}
+	
+	/* ----------------------------------------------------------------------------------------------
+	* 2) Put XOSC32K as source of Generic Clock Generator 3
+	*/
+	GCLK->GENCTRL[3].reg = GCLK_GENCTRL_SRC(GCLK_GENCTRL_SRC_OSCULP32K) | //generic clock gen 3
+	GCLK_GENCTRL_GENEN;
+
+	while ( GCLK->SYNCBUSY.reg & GCLK_SYNCBUSY_GENCTRL3 ){
+		/* Wait for synchronization */
+	}
+	
+	/* ----------------------------------------------------------------------------------------------
+	* 3) Put Generic Clock Generator 3 as source for Generic Clock Gen 0 (DFLL48M reference)
+	*/
+	GCLK->GENCTRL[0].reg = GCLK_GENCTRL_SRC(GCLK_GENCTRL_SRC_OSCULP32K) | GCLK_GENCTRL_GENEN;
+	
+	/* ----------------------------------------------------------------------------------------------
+	* 4) Enable DFLL48M clock
+	*/
+
+	/* DFLL Configuration in Open Loop mode */
+
+	OSCCTRL->DFLLCTRLA.reg = 0;
+	//GCLK->PCHCTRL[OSCCTRL_GCLK_ID_DFLL48].reg = (1 << GCLK_PCHCTRL_CHEN_Pos) | GCLK_PCHCTRL_GEN(GCLK_PCHCTRL_GEN_GCLK3_Val);
+
+	OSCCTRL->DFLLMUL.reg = OSCCTRL_DFLLMUL_CSTEP( 0x1 ) |
+	OSCCTRL_DFLLMUL_FSTEP( 0x1 ) |
+	OSCCTRL_DFLLMUL_MUL( 0 );
+
+	while ( OSCCTRL->DFLLSYNC.reg & OSCCTRL_DFLLSYNC_DFLLMUL )
+	{
+		/* Wait for synchronization */
+	}
+	
+	OSCCTRL->DFLLCTRLB.reg = 0;
+	while ( OSCCTRL->DFLLSYNC.reg & OSCCTRL_DFLLSYNC_DFLLCTRLB )
+	{
+		/* Wait for synchronization */
+	}
+	
+	OSCCTRL->DFLLCTRLA.reg |= OSCCTRL_DFLLCTRLA_ENABLE;
+	while ( OSCCTRL->DFLLSYNC.reg & OSCCTRL_DFLLSYNC_ENABLE )
+	{
+		/* Wait for synchronization */
+	}
+	
+	OSCCTRL->DFLLVAL.reg = OSCCTRL->DFLLVAL.reg;
+	while( OSCCTRL->DFLLSYNC.bit.DFLLVAL );
+	
+	OSCCTRL->DFLLCTRLB.reg = OSCCTRL_DFLLCTRLB_WAITLOCK |
+	OSCCTRL_DFLLCTRLB_CCDIS | OSCCTRL_DFLLCTRLB_USBCRM ;
+	
+	while ( !OSCCTRL->STATUS.bit.DFLLRDY )
+	{
+		/* Wait for synchronization */
+	}
+
+	/* ----------------------------------------------------------------------------------------------
+	* 5) Switch Generic Clock Generator 0 to DFLL48M. CPU will run at 48MHz.
+	*/
+	GCLK->GENCTRL[1].reg = GCLK_GENCTRL_SRC(GCLK_GENCTRL_SRC_DFLL) |
+	GCLK_GENCTRL_IDC |
+	GCLK_GENCTRL_OE |
+	GCLK_GENCTRL_GENEN;
+
+	while ( GCLK->SYNCBUSY.reg & GCLK_SYNCBUSY_GENCTRL0 )
+	{
+		/* Wait for synchronization */
+	}
+	
+	// now we want a DPLL0 for MCLK
+	
+	// a reference, from the DFLL, for the DPLL0
+	GCLK->GENCTRL[5].reg = GCLK_GENCTRL_SRC(GCLK_GENCTRL_SRC_DFLL_Val) | GCLK_GENCTRL_GENEN | GCLK_GENCTRL_DIV(24u);
+	while(GCLK->SYNCBUSY.bit.GENCTRL5);
+	
+	// the DPLL setup
+	GCLK->PCHCTRL[OSCCTRL_GCLK_ID_FDPLL0].reg = (1 << GCLK_PCHCTRL_CHEN_Pos) | GCLK_PCHCTRL_GEN(GCLK_PCHCTRL_GEN_GCLK5_Val);
+	OSCCTRL->Dpll[0].DPLLRATIO.reg = OSCCTRL_DPLLRATIO_LDRFRAC(0x00) | OSCCTRL_DPLLRATIO_LDR(59);
+	while(OSCCTRL->Dpll[0].DPLLSYNCBUSY.bit.DPLLRATIO);
+	OSCCTRL->Dpll[0].DPLLCTRLB.reg = OSCCTRL_DPLLCTRLB_REFCLK_GCLK | OSCCTRL_DPLLCTRLB_LBYPASS;
+	OSCCTRL->Dpll[0].DPLLCTRLA.reg = OSCCTRL_DPLLCTRLA_ENABLE;
+	while(OSCCTRL->Dpll[0].DPLLSTATUS.bit.CLKRDY == 0 || OSCCTRL->Dpll[0].DPLLSTATUS.bit.LOCK == 0);
+	// set clock to use dpll0
+	
+	// this would switch the CPU clock to the DPLL0
+	GCLK->GENCTRL[0].reg = GCLK_GENCTRL_SRC(GCLK_GENCTRL_SRC_DPLL0) | GCLK_GENCTRL_IDC | GCLK_GENCTRL_GENEN;
+	while(GCLK->SYNCBUSY.reg & GCLK_SYNCBUSY_GENCTRL0);
+	
+	/* Turn on the digital interface clock */
+	//MCLK->APBAMASK.reg |= MCLK_APBAMASK_GCLK;
+
+	/*
+	* Now that all system clocks are configured, we can set CLKDIV .
+	* These values are normally the ones present after Reset.
+	*/
+	MCLK->CPUDIV.reg = MCLK_CPUDIV_DIV_DIV1;
+}
\ No newline at end of file
diff --git a/embedded/mkrouter-v06/mkrouter-v06/hardware.h b/embedded/mkrouter-v06/mkrouter-v06/hardware.h
new file mode 100644
index 0000000000000000000000000000000000000000..fdf9962a468bedba82fa5b2c8c473fbb1d3506f8
--- /dev/null
+++ b/embedded/mkrouter-v06/mkrouter-v06/hardware.h
@@ -0,0 +1,103 @@
+/*
+ * hardware.h
+ *
+ * Created: 5/18/2018 11:01:12 AM
+ *  Author: Jake
+ */ 
+
+
+
+
+#ifndef HARDWARE_H_
+#define HARDWARE_H_
+
+#include "pin.h"
+
+/* USB PINS
+
+USBDM		PA24	USB
+USBDP		PA25	USB
+*/
+
+/* STATUS LIGHTS
+
+STLTICKER	PA03
+STLUSB		PA02
+STLPACKET	PB03
+STLERR		PB02
+*/
+
+pin_t stlTicker;
+pin_t stlUsb;
+pin_t stlPacket;
+pin_t stlErr;
+
+/*
+UP0RX		PA05	SER0-1
+UP0TX		PA04	SER0-0
+UP0STLB		PB22	(on receive)
+UP0STLR		PB31	(on transmit)
+*/
+
+
+pin_t up0stlb;
+pin_t up0stlr;
+
+
+/*
+UP1RX		PA01	SER1-1
+UP1TX		PA00	SER1-0
+UP1STLB		PA20
+UP1STLR		PA21
+*/
+
+
+pin_t up1stlb;
+pin_t up1stlr;
+
+/*
+UP2RX		PA08	SER2-1
+UP2TX		PA09	SER2-0
+UP2STLB		PB16
+UP2STLR		PB17 
+*/
+
+
+pin_t up2stlb;
+pin_t up2stlr;
+
+/*
+UP3RX		PA16	SER3-1
+UP3TX		PA17	SER3-0
+UP3STLB		PA18 
+UP3STLR		PA19
+*/
+
+
+pin_t up3stlb;
+pin_t up3stlr;
+
+/*
+UP4RX		PA12	SER4-1
+UP4TX		PA13	SER4-0
+UP4STLB		PA14 
+UP4STLR		PA15 
+*/
+
+
+pin_t up4stlb;
+pin_t up4stlr;
+
+/*
+UP5RX		PA22	SER5-1
+UP5TX		PA23	SER5-0
+UP5STLB		PB13
+UP5STLR		PB14
+*/
+
+
+pin_t up5stlb;
+pin_t up5stlr;
+
+
+#endif /* HARDWARE_H_ */
\ No newline at end of file
diff --git a/embedded/mkrouter-v06/mkrouter-v06/main.c b/embedded/mkrouter-v06/mkrouter-v06/main.c
new file mode 100644
index 0000000000000000000000000000000000000000..eee87c24c3946c2eb89983788e5ef518d1a613ba
--- /dev/null
+++ b/embedded/mkrouter-v06/mkrouter-v06/main.c
@@ -0,0 +1,140 @@
+/*
+ * usb-adafruit-cdc.c
+ *
+ * Created: 5/3/2018 6:39:05 PM
+ * Author : Jake
+ */ 
+
+#include <stdio.h>
+#include "sam.h"
+#include "sam_ba_usb.h"
+#include "sam_ba_monitor.h"
+
+#include "hardware.h"
+
+void lights_init(void){
+	stlTicker = pin_new(0, 3);
+	pin_output(&stlTicker);
+	pin_set(&stlTicker);
+	stlUsb = pin_new(0, 2);
+	pin_output(&stlUsb);
+	pin_set(&stlUsb);
+	stlPacket = pin_new(1, 3);
+	pin_output(&stlPacket);
+	pin_set(&stlPacket);
+	stlErr = pin_new(1, 2);
+	pin_output(&stlErr);
+	pin_set(&stlErr);
+	
+	up0stlb = pin_new(1, 22);
+	pin_output(&up0stlb);
+	pin_set(&up0stlb);
+	up0stlr = pin_new(1, 31);
+	pin_output(&up0stlr);
+	pin_set(&up0stlr);
+	
+	up1stlb = pin_new(0, 20);
+	pin_output(&up1stlb);
+	pin_set(&up1stlb);
+	up1stlr = pin_new(0, 21);
+	pin_output(&up1stlr);
+	pin_set(&up1stlr);
+	
+	up2stlb = pin_new(1, 16);
+	pin_output(&up2stlb);
+	pin_set(&up2stlb);
+	up2stlr = pin_new(1, 17);
+	pin_output(&up2stlr);
+	pin_set(&up2stlr);
+	
+	up3stlb = pin_new(0, 18);
+	pin_output(&up3stlb);
+	pin_set(&up3stlb);
+	up3stlr = pin_new(0, 19);
+	pin_output(&up3stlr);
+	pin_set(&up3stlr);
+	
+	up4stlb = pin_new(0, 14);
+	pin_output(&up4stlb);
+	pin_set(&up4stlb);
+	up4stlr = pin_new(0, 15);
+	pin_output(&up4stlr);
+	pin_set(&up4stlr);
+	
+	up5stlb = pin_new(1, 13);
+	pin_output(&up5stlb);
+	pin_set(&up5stlb);
+	up5stlr = pin_new(1, 14);
+	pin_output(&up5stlr);
+	pin_set(&up5stlr);
+}
+
+static volatile bool main_b_cdc_enable = false;
+
+int main(void)
+{
+    /* Initialize the SAM system */
+    SystemInit();
+	// clock setup to run main CPU at 120MHz, and DFLL48M setup from internal osc, should run USB
+	clock_init();
+	// enable interrupts in the system
+	__enable_irq();
+	
+	lights_init();
+		
+	// pointer to the USB struct in sam_ba_usb.h
+	P_USB_CDC pCdc; 
+	
+	// turn the USB on, sam_ba_usb.h and .c
+	pCdc = usb_init();
+	
+	// a ticker to look for hangouts
+	SysTick_Config(8000000);
+
+    /* Replace with your application code */
+    while (1) 
+    {
+
+		// waits for config to config
+		if(pCdc->IsConfigured(pCdc) != 0){
+			main_b_cdc_enable = true;
+			pin_clear(&stlUsb);
+		}
+		
+		// if config is config, and port is opened
+		if(main_b_cdc_enable){
+			sam_ba_monitor_init(SAM_BA_INTERFACE_USBCDC);
+			// loops on this
+			while(1){
+				sam_ba_monitor_run();
+				// @ HERE: understand how this /\ runs, looks through buffer etc... 
+				// do the same for (1) bytes -> uart
+				// (2) for packet searching
+			}
+			
+		}
+	}
+}
+
+void SysTick_Handler(void){
+	pin_toggle(&stlTicker);
+	
+	/*
+	pin_toggle(&stlPacket);
+	pin_toggle(&stlErr);
+	
+	pin_toggle(&up0stlb);
+	pin_toggle(&up0stlr);
+	pin_toggle(&up1stlb);
+	pin_toggle(&up1stlr);
+	pin_toggle(&up2stlb);
+	pin_toggle(&up2stlr);
+	pin_toggle(&up3stlb);
+	pin_toggle(&up3stlr);
+	pin_toggle(&up4stlb);
+	pin_toggle(&up4stlr);
+	pin_toggle(&up5stlb);
+	pin_toggle(&up5stlr);
+	*/
+	// monitor_sys_tick
+}
diff --git a/embedded/mkrouter-v06/mkrouter-v06/mkrouter-v06.componentinfo.xml b/embedded/mkrouter-v06/mkrouter-v06/mkrouter-v06.componentinfo.xml
new file mode 100644
index 0000000000000000000000000000000000000000..6c95f24ede707aaf5ba9b16f232623dff15212b9
--- /dev/null
+++ b/embedded/mkrouter-v06/mkrouter-v06/mkrouter-v06.componentinfo.xml
@@ -0,0 +1,169 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Store xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="AtmelPackComponentManagement">
+	<ProjectComponents>
+		<ProjectComponent z:Id="i1" xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/">
+			<CApiVersion></CApiVersion>
+			<CBundle></CBundle>
+			<CClass>CMSIS</CClass>
+			<CGroup>CORE</CGroup>
+			<CSub></CSub>
+			<CVariant></CVariant>
+			<CVendor>ARM</CVendor>
+			<CVersion>5.0.1</CVersion>
+			<DefaultRepoPath>C:/Program Files (x86)\Atmel\Studio\7.0\Packs</DefaultRepoPath>
+			<DependentComponents xmlns:d4p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays" />
+			<Description></Description>
+			<Files xmlns:d4p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
+				<d4p1:anyType i:type="FileInfo">
+					<AbsolutePath>C:/Program Files (x86)\Atmel\Studio\7.0\Packs\arm\CMSIS\5.0.1\CMSIS\Documentation\Core\html\index.html</AbsolutePath>
+					<Attribute></Attribute>
+					<Category>doc</Category>
+					<Condition></Condition>
+					<FileContentHash>Cq3aNYyqgx20hdPs+CNSlQ==</FileContentHash>
+					<FileVersion></FileVersion>
+					<Name>CMSIS/Documentation/Core/html/index.html</Name>
+					<SelectString></SelectString>
+					<SourcePath></SourcePath>
+				</d4p1:anyType>
+				<d4p1:anyType i:type="FileInfo">
+					<AbsolutePath>C:/Program Files (x86)\Atmel\Studio\7.0\Packs\arm\CMSIS\5.0.1\CMSIS\Include\</AbsolutePath>
+					<Attribute></Attribute>
+					<Category>include</Category>
+					<Condition></Condition>
+					<FileContentHash i:nil="true" />
+					<FileVersion></FileVersion>
+					<Name>CMSIS/Include/</Name>
+					<SelectString></SelectString>
+					<SourcePath></SourcePath>
+				</d4p1:anyType>
+			</Files>
+			<PackName>CMSIS</PackName>
+			<PackPath>C:/Program Files (x86)/Atmel/Studio/7.0/Packs/arm/CMSIS/5.0.1/ARM.CMSIS.pdsc</PackPath>
+			<PackVersion>5.0.1</PackVersion>
+			<PresentInProject>true</PresentInProject>
+			<ReferenceConditionId>ARMv6_7_8-M Device</ReferenceConditionId>
+			<RteComponents xmlns:d4p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
+				<d4p1:string></d4p1:string>
+			</RteComponents>
+			<Status>Resolved</Status>
+			<VersionMode>Fixed</VersionMode>
+			<IsComponentInAtProject>true</IsComponentInAtProject>
+		</ProjectComponent>
+		<ProjectComponent z:Id="i2" xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/">
+			<CApiVersion></CApiVersion>
+			<CBundle></CBundle>
+			<CClass>Device</CClass>
+			<CGroup>Startup</CGroup>
+			<CSub></CSub>
+			<CVariant></CVariant>
+			<CVendor>Atmel</CVendor>
+			<CVersion>1.0.0</CVersion>
+			<DefaultRepoPath>C:/Program Files (x86)\Atmel\Studio\7.0\Packs</DefaultRepoPath>
+			<DependentComponents xmlns:d4p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
+				<d4p1:anyType z:Ref="i1" />
+			</DependentComponents>
+			<Description></Description>
+			<Files xmlns:d4p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
+				<d4p1:anyType i:type="FileInfo">
+					<AbsolutePath>C:/Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\SAMD51_DFP\1.0.70\include</AbsolutePath>
+					<Attribute></Attribute>
+					<Category>include</Category>
+					<Condition>C</Condition>
+					<FileContentHash i:nil="true" />
+					<FileVersion></FileVersion>
+					<Name>include</Name>
+					<SelectString></SelectString>
+					<SourcePath></SourcePath>
+				</d4p1:anyType>
+				<d4p1:anyType i:type="FileInfo">
+					<AbsolutePath>C:/Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\SAMD51_DFP\1.0.70\include\sam.h</AbsolutePath>
+					<Attribute></Attribute>
+					<Category>header</Category>
+					<Condition>C</Condition>
+					<FileContentHash>vyFU01H27yMwm8jt09KCJw==</FileContentHash>
+					<FileVersion></FileVersion>
+					<Name>include/sam.h</Name>
+					<SelectString></SelectString>
+					<SourcePath></SourcePath>
+				</d4p1:anyType>
+				<d4p1:anyType i:type="FileInfo">
+					<AbsolutePath>C:/Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\SAMD51_DFP\1.0.70\templates\main.c</AbsolutePath>
+					<Attribute>template</Attribute>
+					<Category>source</Category>
+					<Condition>C Exe</Condition>
+					<FileContentHash>D26ik9ZEc+nxso7EbtTH+Q==</FileContentHash>
+					<FileVersion></FileVersion>
+					<Name>templates/main.c</Name>
+					<SelectString>Main file (.c)</SelectString>
+					<SourcePath></SourcePath>
+				</d4p1:anyType>
+				<d4p1:anyType i:type="FileInfo">
+					<AbsolutePath>C:/Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\SAMD51_DFP\1.0.70\templates\main.cpp</AbsolutePath>
+					<Attribute>template</Attribute>
+					<Category>source</Category>
+					<Condition>C Exe</Condition>
+					<FileContentHash>nU+WlKcYaWh0AWBBS+WVpA==</FileContentHash>
+					<FileVersion></FileVersion>
+					<Name>templates/main.cpp</Name>
+					<SelectString>Main file (.cpp)</SelectString>
+					<SourcePath></SourcePath>
+				</d4p1:anyType>
+				<d4p1:anyType i:type="FileInfo">
+					<AbsolutePath>C:/Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\SAMD51_DFP\1.0.70\gcc\system_samd51.c</AbsolutePath>
+					<Attribute>config</Attribute>
+					<Category>source</Category>
+					<Condition>GCC Exe</Condition>
+					<FileContentHash>48bRDDtXyAiZjWlKI3+D+A==</FileContentHash>
+					<FileVersion></FileVersion>
+					<Name>gcc/system_samd51.c</Name>
+					<SelectString></SelectString>
+					<SourcePath></SourcePath>
+				</d4p1:anyType>
+				<d4p1:anyType i:type="FileInfo">
+					<AbsolutePath>C:/Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\SAMD51_DFP\1.0.70\gcc\gcc\startup_samd51.c</AbsolutePath>
+					<Attribute>config</Attribute>
+					<Category>source</Category>
+					<Condition>GCC Exe</Condition>
+					<FileContentHash>R2AbfQpzs4ooHNhxYaFLYA==</FileContentHash>
+					<FileVersion></FileVersion>
+					<Name>gcc/gcc/startup_samd51.c</Name>
+					<SelectString></SelectString>
+					<SourcePath></SourcePath>
+				</d4p1:anyType>
+				<d4p1:anyType i:type="FileInfo">
+					<AbsolutePath>C:/Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\SAMD51_DFP\1.0.70\gcc\gcc\samd51j18a_flash.ld</AbsolutePath>
+					<Attribute>config</Attribute>
+					<Category>linkerScript</Category>
+					<Condition>GCC Exe</Condition>
+					<FileContentHash>CF4FN7Jc1GGlwWZRgaNJqA==</FileContentHash>
+					<FileVersion></FileVersion>
+					<Name>gcc/gcc/samd51j18a_flash.ld</Name>
+					<SelectString></SelectString>
+					<SourcePath></SourcePath>
+				</d4p1:anyType>
+				<d4p1:anyType i:type="FileInfo">
+					<AbsolutePath>C:/Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\SAMD51_DFP\1.0.70\gcc\gcc\samd51j18a_sram.ld</AbsolutePath>
+					<Attribute>config</Attribute>
+					<Category>other</Category>
+					<Condition>GCC Exe</Condition>
+					<FileContentHash>UCVgCIkMhtRrpTXgb0K8mg==</FileContentHash>
+					<FileVersion></FileVersion>
+					<Name>gcc/gcc/samd51j18a_sram.ld</Name>
+					<SelectString></SelectString>
+					<SourcePath></SourcePath>
+				</d4p1:anyType>
+			</Files>
+			<PackName>SAMD51_DFP</PackName>
+			<PackPath>C:/Program Files (x86)/Atmel/Studio/7.0/Packs/atmel/SAMD51_DFP/1.0.70/Atmel.SAMD51_DFP.pdsc</PackPath>
+			<PackVersion>1.0.70</PackVersion>
+			<PresentInProject>true</PresentInProject>
+			<ReferenceConditionId>ATSAMD51J18A</ReferenceConditionId>
+			<RteComponents xmlns:d4p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
+				<d4p1:string></d4p1:string>
+			</RteComponents>
+			<Status>Resolved</Status>
+			<VersionMode>Fixed</VersionMode>
+			<IsComponentInAtProject>true</IsComponentInAtProject>
+		</ProjectComponent>
+	</ProjectComponents>
+</Store>
\ No newline at end of file
diff --git a/embedded/mkrouter-v06/mkrouter-v06/mkrouter-v06.cproj b/embedded/mkrouter-v06/mkrouter-v06/mkrouter-v06.cproj
new file mode 100644
index 0000000000000000000000000000000000000000..26fc1eba881cceb7a30e7d3b790814a68cfd3c71
--- /dev/null
+++ b/embedded/mkrouter-v06/mkrouter-v06/mkrouter-v06.cproj
@@ -0,0 +1,235 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="14.0">
+  <PropertyGroup>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectVersion>7.0</ProjectVersion>
+    <ToolchainName>com.Atmel.ARMGCC.C</ToolchainName>
+    <ProjectGuid>dce6c7e3-ee26-4d79-826b-08594b9ad897</ProjectGuid>
+    <avrdevice>ATSAMD51J18A</avrdevice>
+    <avrdeviceseries>none</avrdeviceseries>
+    <OutputType>Executable</OutputType>
+    <Language>C</Language>
+    <OutputFileName>$(MSBuildProjectName)</OutputFileName>
+    <OutputFileExtension>.elf</OutputFileExtension>
+    <OutputDirectory>$(MSBuildProjectDirectory)\$(Configuration)</OutputDirectory>
+    <AssemblyName>mkrouter-v06</AssemblyName>
+    <Name>mkrouter-v06</Name>
+    <RootNamespace>mkrouter-v06</RootNamespace>
+    <ToolchainFlavour>Native</ToolchainFlavour>
+    <KeepTimersRunning>true</KeepTimersRunning>
+    <OverrideVtor>false</OverrideVtor>
+    <CacheFlash>true</CacheFlash>
+    <ProgFlashFromRam>true</ProgFlashFromRam>
+    <RamSnippetAddress>0x20000000</RamSnippetAddress>
+    <UncachedRange />
+    <preserveEEPROM>true</preserveEEPROM>
+    <OverrideVtorValue>exception_table</OverrideVtorValue>
+    <BootSegment>2</BootSegment>
+    <ResetRule>0</ResetRule>
+    <eraseonlaunchrule>0</eraseonlaunchrule>
+    <EraseKey />
+    <AsfFrameworkConfig>
+      <framework-data xmlns="">
+        <options />
+        <configurations />
+        <files />
+        <documentation help="" />
+        <offline-documentation help="" />
+        <dependencies>
+          <content-extension eid="atmel.asf" uuidref="Atmel.ASF" version="3.39.0" />
+        </dependencies>
+      </framework-data>
+    </AsfFrameworkConfig>
+    <avrtool>com.atmel.avrdbg.tool.atmelice</avrtool>
+    <avrtoolserialnumber>J41800087098</avrtoolserialnumber>
+    <avrdeviceexpectedsignature>0x60060006</avrdeviceexpectedsignature>
+    <avrtoolinterface>SWD</avrtoolinterface>
+    <com_atmel_avrdbg_tool_atmelice>
+      <ToolOptions>
+        <InterfaceProperties>
+          <SwdClock>2000000</SwdClock>
+        </InterfaceProperties>
+        <InterfaceName>SWD</InterfaceName>
+      </ToolOptions>
+      <ToolType>com.atmel.avrdbg.tool.atmelice</ToolType>
+      <ToolNumber>J41800087098</ToolNumber>
+      <ToolName>Atmel-ICE</ToolName>
+    </com_atmel_avrdbg_tool_atmelice>
+    <avrtoolinterfaceclock>2000000</avrtoolinterfaceclock>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
+    <ToolchainSettings>
+      <ArmGcc>
+  <armgcc.common.outputfiles.hex>True</armgcc.common.outputfiles.hex>
+  <armgcc.common.outputfiles.lss>True</armgcc.common.outputfiles.lss>
+  <armgcc.common.outputfiles.eep>True</armgcc.common.outputfiles.eep>
+  <armgcc.common.outputfiles.bin>True</armgcc.common.outputfiles.bin>
+  <armgcc.common.outputfiles.srec>True</armgcc.common.outputfiles.srec>
+  <armgcc.compiler.symbols.DefSymbols>
+    <ListValues>
+      <Value>NDEBUG</Value>
+    </ListValues>
+  </armgcc.compiler.symbols.DefSymbols>
+  <armgcc.compiler.directories.IncludePaths>
+    <ListValues>
+      <Value>%24(PackRepoDir)\arm\CMSIS\5.0.1\CMSIS\Include\</Value>
+      <Value>%24(PackRepoDir)\atmel\SAMD51_DFP\1.0.70\include</Value>
+    </ListValues>
+  </armgcc.compiler.directories.IncludePaths>
+  <armgcc.compiler.optimization.level>Optimize for size (-Os)</armgcc.compiler.optimization.level>
+  <armgcc.compiler.optimization.PrepareFunctionsForGarbageCollection>True</armgcc.compiler.optimization.PrepareFunctionsForGarbageCollection>
+  <armgcc.compiler.warnings.AllWarnings>True</armgcc.compiler.warnings.AllWarnings>
+  <armgcc.linker.libraries.Libraries>
+    <ListValues>
+      <Value>libm</Value>
+    </ListValues>
+  </armgcc.linker.libraries.Libraries>
+  <armgcc.linker.libraries.LibrarySearchPaths>
+    <ListValues>
+      <Value>%24(ProjectDir)\Device_Startup</Value>
+    </ListValues>
+  </armgcc.linker.libraries.LibrarySearchPaths>
+  <armgcc.linker.optimization.GarbageCollectUnusedSections>True</armgcc.linker.optimization.GarbageCollectUnusedSections>
+  <armgcc.linker.miscellaneous.LinkerFlags>-Tsamd51j18a_flash.ld</armgcc.linker.miscellaneous.LinkerFlags>
+  <armgcc.assembler.general.IncludePaths>
+    <ListValues>
+      <Value>%24(PackRepoDir)\arm\CMSIS\5.0.1\CMSIS\Include\</Value>
+      <Value>%24(PackRepoDir)\atmel\SAMD51_DFP\1.0.70\include</Value>
+    </ListValues>
+  </armgcc.assembler.general.IncludePaths>
+  <armgcc.preprocessingassembler.general.IncludePaths>
+    <ListValues>
+      <Value>%24(PackRepoDir)\arm\CMSIS\5.0.1\CMSIS\Include\</Value>
+      <Value>%24(PackRepoDir)\atmel\SAMD51_DFP\1.0.70\include</Value>
+    </ListValues>
+  </armgcc.preprocessingassembler.general.IncludePaths>
+</ArmGcc>
+    </ToolchainSettings>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
+    <ToolchainSettings>
+      <ArmGcc>
+  <armgcc.common.outputfiles.hex>True</armgcc.common.outputfiles.hex>
+  <armgcc.common.outputfiles.lss>True</armgcc.common.outputfiles.lss>
+  <armgcc.common.outputfiles.eep>True</armgcc.common.outputfiles.eep>
+  <armgcc.common.outputfiles.bin>True</armgcc.common.outputfiles.bin>
+  <armgcc.common.outputfiles.srec>True</armgcc.common.outputfiles.srec>
+  <armgcc.compiler.symbols.DefSymbols>
+    <ListValues>
+      <Value>DEBUG</Value>
+    </ListValues>
+  </armgcc.compiler.symbols.DefSymbols>
+  <armgcc.compiler.directories.IncludePaths>
+    <ListValues>
+      <Value>%24(PackRepoDir)\arm\CMSIS\5.0.1\CMSIS\Include\</Value>
+      <Value>%24(PackRepoDir)\atmel\SAMD51_DFP\1.0.70\include</Value>
+    </ListValues>
+  </armgcc.compiler.directories.IncludePaths>
+  <armgcc.compiler.optimization.level>Optimize (-O1)</armgcc.compiler.optimization.level>
+  <armgcc.compiler.optimization.PrepareFunctionsForGarbageCollection>True</armgcc.compiler.optimization.PrepareFunctionsForGarbageCollection>
+  <armgcc.compiler.optimization.DebugLevel>Maximum (-g3)</armgcc.compiler.optimization.DebugLevel>
+  <armgcc.compiler.warnings.AllWarnings>True</armgcc.compiler.warnings.AllWarnings>
+  <armgcc.linker.libraries.Libraries>
+    <ListValues>
+      <Value>libm</Value>
+    </ListValues>
+  </armgcc.linker.libraries.Libraries>
+  <armgcc.linker.libraries.LibrarySearchPaths>
+    <ListValues>
+      <Value>%24(ProjectDir)\Device_Startup</Value>
+    </ListValues>
+  </armgcc.linker.libraries.LibrarySearchPaths>
+  <armgcc.linker.optimization.GarbageCollectUnusedSections>True</armgcc.linker.optimization.GarbageCollectUnusedSections>
+  <armgcc.linker.miscellaneous.LinkerFlags>-Tsamd51j18a_flash.ld</armgcc.linker.miscellaneous.LinkerFlags>
+  <armgcc.assembler.general.IncludePaths>
+    <ListValues>
+      <Value>%24(PackRepoDir)\arm\CMSIS\5.0.1\CMSIS\Include\</Value>
+      <Value>%24(PackRepoDir)\atmel\SAMD51_DFP\1.0.70\include</Value>
+    </ListValues>
+  </armgcc.assembler.general.IncludePaths>
+  <armgcc.assembler.debugging.DebugLevel>Default (-g)</armgcc.assembler.debugging.DebugLevel>
+  <armgcc.preprocessingassembler.general.IncludePaths>
+    <ListValues>
+      <Value>%24(PackRepoDir)\arm\CMSIS\5.0.1\CMSIS\Include\</Value>
+      <Value>%24(PackRepoDir)\atmel\SAMD51_DFP\1.0.70\include</Value>
+    </ListValues>
+  </armgcc.preprocessingassembler.general.IncludePaths>
+  <armgcc.preprocessingassembler.debugging.DebugLevel>Default (-Wa,-g)</armgcc.preprocessingassembler.debugging.DebugLevel>
+</ArmGcc>
+    </ToolchainSettings>
+  </PropertyGroup>
+  <ItemGroup>
+    <Compile Include="board_definitions.h">
+      <SubType>compile</SubType>
+    </Compile>
+    <Compile Include="board_driver_serial.c">
+      <SubType>compile</SubType>
+    </Compile>
+    <Compile Include="board_driver_serial.h">
+      <SubType>compile</SubType>
+    </Compile>
+    <Compile Include="board_driver_usb.c">
+      <SubType>compile</SubType>
+    </Compile>
+    <Compile Include="board_driver_usb.h">
+      <SubType>compile</SubType>
+    </Compile>
+    <Compile Include="clock_init.c">
+      <SubType>compile</SubType>
+    </Compile>
+    <Compile Include="Device_Startup\startup_samd51.c">
+      <SubType>compile</SubType>
+    </Compile>
+    <Compile Include="Device_Startup\system_samd51.c">
+      <SubType>compile</SubType>
+    </Compile>
+    <Compile Include="hardware.h">
+      <SubType>compile</SubType>
+    </Compile>
+    <Compile Include="main.c">
+      <SubType>compile</SubType>
+    </Compile>
+    <Compile Include="pin.c">
+      <SubType>compile</SubType>
+    </Compile>
+    <Compile Include="pin.h">
+      <SubType>compile</SubType>
+    </Compile>
+    <Compile Include="sam_ba_cdc.c">
+      <SubType>compile</SubType>
+    </Compile>
+    <Compile Include="sam_ba_cdc.h">
+      <SubType>compile</SubType>
+    </Compile>
+    <Compile Include="sam_ba_monitor.c">
+      <SubType>compile</SubType>
+    </Compile>
+    <Compile Include="sam_ba_monitor.h">
+      <SubType>compile</SubType>
+    </Compile>
+    <Compile Include="sam_ba_serial.c">
+      <SubType>compile</SubType>
+    </Compile>
+    <Compile Include="sam_ba_serial.h">
+      <SubType>compile</SubType>
+    </Compile>
+    <Compile Include="sam_ba_usb.c">
+      <SubType>compile</SubType>
+    </Compile>
+    <Compile Include="sam_ba_usb.h">
+      <SubType>compile</SubType>
+    </Compile>
+  </ItemGroup>
+  <ItemGroup>
+    <Folder Include="Device_Startup\" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="Device_Startup\samd51j18a_flash.ld">
+      <SubType>compile</SubType>
+    </None>
+    <None Include="Device_Startup\samd51j18a_sram.ld">
+      <SubType>compile</SubType>
+    </None>
+  </ItemGroup>
+  <Import Project="$(AVRSTUDIO_EXE_PATH)\\Vs\\Compiler.targets" />
+</Project>
\ No newline at end of file
diff --git a/embedded/mkrouter-v06/mkrouter-v06/pin.c b/embedded/mkrouter-v06/mkrouter-v06/pin.c
new file mode 100644
index 0000000000000000000000000000000000000000..957565a4845995d8ee26ec13972a4ea81f73d6fb
--- /dev/null
+++ b/embedded/mkrouter-v06/mkrouter-v06/pin.c
@@ -0,0 +1,48 @@
+/*
+ * pin.c
+ *
+ * Created: 2/5/2018 11:21:37 PM
+ *  Author: Jake
+ */ 
+
+#include "pin.h"
+#include "sam.h"
+
+pin_t pin_new(uint32_t portNumber, uint32_t pin_number){
+	pin_t pin;
+	pin.port = &PORT->Group[portNumber];
+	pin.bm = (uint32_t)(1 << pin_number);
+	pin.pos = pin_number;
+	return pin;
+}
+
+
+void pin_output(pin_t *pin){
+	pin->port->DIRSET.reg = pin->bm;
+	pin->port->OUTCLR.reg = pin->bm;
+}
+
+void pin_input(pin_t *pin){
+	pin->port->DIRCLR.reg = pin->bm;
+	pin->port->PINCFG[pin->pos].bit.INEN = 1;
+}
+
+void pin_pullen(pin_t *pin){
+	pin->port->PINCFG[pin->pos].bit.PULLEN = 1;
+}
+
+void pin_set(pin_t *pin){
+	pin->port->OUTSET.reg = pin->bm;
+}
+
+void pin_clear(pin_t *pin){
+	pin->port->OUTCLR.reg = pin->bm;
+}
+
+void pin_toggle(pin_t *pin){
+	pin->port->OUTTGL.reg = pin->bm;
+}
+
+int pin_read(pin_t *pin){
+	return pin->port->IN.reg & pin->bm;
+}
diff --git a/embedded/mkrouter-v06/mkrouter-v06/pin.h b/embedded/mkrouter-v06/mkrouter-v06/pin.h
new file mode 100644
index 0000000000000000000000000000000000000000..387d5e50f7f2069568198b8df37091365cb72602
--- /dev/null
+++ b/embedded/mkrouter-v06/mkrouter-v06/pin.h
@@ -0,0 +1,32 @@
+/*
+ * pin.h
+ *
+ * Created: 2/5/2018 11:21:47 PM
+ *  Author: Jake
+ */ 
+
+
+#ifndef PIN_H_
+#define PIN_H_
+
+#include "sam.h"
+
+typedef struct {
+	PortGroup *port;
+	uint32_t bm; // bitmask
+	uint32_t pos;
+} pin_t;
+
+pin_t pin_new(uint32_t portNumber, uint32_t pin);
+
+void pin_output(pin_t *pin);
+void pin_input(pin_t *pin);
+void pin_pullen(pin_t *pin);
+
+void pin_set(pin_t *pin);
+void pin_clear(pin_t *pin);
+void pin_toggle(pin_t *pin);
+
+int pin_read(pin_t *pin);
+
+#endif /* PIN_H_ */
diff --git a/embedded/mkrouter-v06/mkrouter-v06/sam_ba_cdc.c b/embedded/mkrouter-v06/mkrouter-v06/sam_ba_cdc.c
new file mode 100644
index 0000000000000000000000000000000000000000..377340921b7688d0741cec58fee38a1835a47ff4
--- /dev/null
+++ b/embedded/mkrouter-v06/mkrouter-v06/sam_ba_cdc.c
@@ -0,0 +1,98 @@
+/*
+  Copyright (c) 2015 Arduino LLC.  All right reserved.
+  Copyright (c) 2015 Atmel Corporation/Thibaut VIARD.  All right reserved.
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  This library 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 Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+
+#include "sam_ba_cdc.h"
+#include "board_driver_usb.h"
+
+usb_cdc_line_coding_t line_coding=
+{
+  115200, // baudrate
+  0,      // 1 Stop Bit
+  0,      // None Parity
+  8     // 8 Data bits
+};
+
+#define pCdc (&sam_ba_cdc)
+
+int cdc_putc(/*P_USB_CDC pCdc,*/ int value)
+{
+  /* Send single byte on USB CDC */
+  USB_Write(pCdc->pUsb, (const char *)&value, 1, USB_EP_IN);
+
+  return 1;
+}
+
+int cdc_getc(/*P_USB_CDC pCdc*/void)
+{
+  uint8_t rx_char;
+
+  /* Read singly byte on USB CDC */
+  USB_Read(pCdc->pUsb, (char *)&rx_char, 1);
+
+  return (int)rx_char;
+}
+
+bool cdc_is_rx_ready(/*P_USB_CDC pCdc*/void)
+{
+  /* Check whether the device is configured */
+  if ( !USB_IsConfigured(pCdc) )
+    return 0;
+
+  /* Return transfer complete 0 flag status */
+  return (pCdc->pUsb->DEVICE.DeviceEndpoint[USB_EP_OUT].EPINTFLAG.bit.TRCPT0);
+}
+
+uint32_t cdc_write_buf(/*P_USB_CDC pCdc,*/ void const* data, uint32_t length)
+{
+  /* Send the specified number of bytes on USB CDC */
+  USB_Write(pCdc->pUsb, (const char *)data, length, USB_EP_IN);
+  return length;
+}
+
+uint32_t cdc_read_buf(/*P_USB_CDC pCdc,*/ void* data, uint32_t length)
+{
+  /* Check whether the device is configured */
+  if ( !USB_IsConfigured(pCdc) )
+    return 0;
+
+  /* Read from USB CDC */
+  return USB_Read(pCdc->pUsb, (char *)data, length);
+}
+
+uint32_t cdc_read_buf_xmd(/*P_USB_CDC pCdc,*/ void* data, uint32_t length)
+{
+  /* Check whether the device is configured */
+  if ( !USB_IsConfigured(pCdc) )
+    return 0;
+
+  /* Blocking read till specified number of bytes is received */
+  // XXX: USB_Read_blocking is not reliable
+  // return USB_Read_blocking(pCdc, (char *)data, length);
+
+  char *dst = (char *)data;
+  uint32_t remaining = length;
+  while (remaining)
+  {
+    uint32_t readed = USB_Read(pCdc->pUsb, (char *)dst, remaining);
+    remaining -= readed;
+    dst += readed;
+  }
+
+  return length;
+}
diff --git a/embedded/mkrouter-v06/mkrouter-v06/sam_ba_cdc.h b/embedded/mkrouter-v06/mkrouter-v06/sam_ba_cdc.h
new file mode 100644
index 0000000000000000000000000000000000000000..49b7643cfb5492d1efe342cb8322accc8b94b16d
--- /dev/null
+++ b/embedded/mkrouter-v06/mkrouter-v06/sam_ba_cdc.h
@@ -0,0 +1,91 @@
+/*
+  Copyright (c) 2015 Arduino LLC.  All right reserved.
+  Copyright (c) 2015 Atmel Corporation/Thibaut VIARD.  All right reserved.
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  This library 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 Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+
+#ifndef _SAM_BA_USB_CDC_H_
+#define _SAM_BA_USB_CDC_H_
+
+#include <stdint.h>
+#include "sam_ba_usb.h"
+
+typedef struct
+{
+	uint32_t dwDTERate;
+	uint8_t bCharFormat;
+	uint8_t bParityType;
+	uint8_t bDataBits;
+} usb_cdc_line_coding_t;
+
+/* CDC Class Specific Request Code */
+#define GET_LINE_CODING               0x21A1
+#define SET_LINE_CODING               0x2021
+#define SET_CONTROL_LINE_STATE        0x2221
+
+extern usb_cdc_line_coding_t line_coding;
+
+
+/**
+ * \brief Sends a single byte through USB CDC
+ *
+ * \param Data to send
+ * \return number of data sent
+ */
+int cdc_putc(/*P_USB_CDC pCdc,*/ int value);
+
+/**
+ * \brief Reads a single byte through USB CDC
+ *
+ * \return Data read through USB
+ */
+int cdc_getc(/*P_USB_CDC pCdc*/);
+
+/**
+ * \brief Checks if a character has been received on USB CDC
+ *
+ * \return \c 1 if a byte is ready to be read.
+ */
+bool cdc_is_rx_ready(/*P_USB_CDC pCdc*/);
+
+/**
+ * \brief Sends buffer on USB CDC
+ *
+ * \param data pointer
+ * \param number of data to send
+ * \return number of data sent
+ */
+uint32_t cdc_write_buf(/*P_USB_CDC pCdc,*/ void const* data, uint32_t length);
+
+/**
+ * \brief Gets data on USB CDC
+ *
+ * \param data pointer
+ * \param number of data to read
+ * \return number of data read
+ */
+uint32_t cdc_read_buf(/*P_USB_CDC pCdc,*/ void* data, uint32_t length);
+
+/**
+ * \brief Gets specified number of bytes on USB CDC
+ *
+ * \param data pointer
+ * \param number of data to read
+ * \return number of data read
+ */
+uint32_t cdc_read_buf_xmd(/*P_USB_CDC pCdc,*/ void* data, uint32_t length);
+
+#endif // _SAM_BA_USB_CDC_H_
diff --git a/embedded/mkrouter-v06/mkrouter-v06/sam_ba_monitor.c b/embedded/mkrouter-v06/mkrouter-v06/sam_ba_monitor.c
new file mode 100644
index 0000000000000000000000000000000000000000..79c5ede56024ba151ddee101371786e4fb97ffa5
--- /dev/null
+++ b/embedded/mkrouter-v06/mkrouter-v06/sam_ba_monitor.c
@@ -0,0 +1,322 @@
+/*
+Copyright (c) 2015 Arduino LLC.  All right reserved.
+Copyright (c) 2015 Atmel Corporation/Thibaut VIARD.  All right reserved.
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+
+#include "sam.h"
+#include <string.h>
+#include "sam_ba_monitor.h"
+#include "sam_ba_serial.h"
+#include "board_driver_serial.h"
+#include "board_driver_usb.h"
+#include "sam_ba_usb.h"
+#include "sam_ba_cdc.h"
+//#include "board_driver_led.h"
+
+const char RomBOOT_Version[] = SAM_BA_VERSION;
+const char RomBOOT_ExtendedCapabilities[] = "[Arduino:XYZ]";
+
+//messy check for port open 
+
+uint8_t usbComOpen = 0;
+
+/* Provides one common interface to handle both USART and USB-CDC */
+typedef struct
+{
+	/* send one byte of data */
+	int (*put_c)(int value);
+	/* Get one byte */
+	int (*get_c)(void);
+	/* Receive buffer not empty */
+	bool (*is_rx_ready)(void);
+	/* Send given data (polling) */
+	uint32_t (*putdata)(void const* data, uint32_t length);
+	/* Get data from comm. device */
+	uint32_t (*getdata)(void* data, uint32_t length);
+	/* Send given data (polling) using xmodem (if necessary) */
+	uint32_t (*putdata_xmd)(void const* data, uint32_t length);
+	/* Get data from comm. device using xmodem (if necessary) */
+	uint32_t (*getdata_xmd)(void* data, uint32_t length);
+} t_monitor_if;
+
+#if SAM_BA_INTERFACE == SAM_BA_UART_ONLY  ||  SAM_BA_INTERFACE == SAM_BA_BOTH_INTERFACES
+/* Initialize structures with function pointers from supported interfaces */
+const t_monitor_if uart_if =
+{
+	.put_c =       serial_putc,
+	.get_c =       serial_getc,
+	.is_rx_ready = serial_is_rx_ready,
+	.putdata =     serial_putdata,
+	.getdata =     serial_getdata,
+	.putdata_xmd = serial_putdata_xmd,
+	.getdata_xmd = serial_getdata_xmd
+};
+#endif
+
+#if SAM_BA_INTERFACE == SAM_BA_USBCDC_ONLY  ||  SAM_BA_INTERFACE == SAM_BA_BOTH_INTERFACES
+//Please note that USB doesn't use Xmodem protocol, since USB already includes flow control and data verification
+//Data are simply forwarded without further coding.
+const t_monitor_if usbcdc_if =
+{
+	.put_c =         cdc_putc,
+	.get_c =         cdc_getc,
+	.is_rx_ready =   cdc_is_rx_ready,
+	.putdata =       cdc_write_buf,
+	.getdata =       cdc_read_buf,
+	.putdata_xmd =   cdc_write_buf,
+	.getdata_xmd =   cdc_read_buf_xmd
+};
+#endif
+
+/* The pointer to the interface object use by the monitor */
+t_monitor_if * ptr_monitor_if;
+
+/* b_terminal_mode mode (ascii) or hex mode */
+volatile bool b_terminal_mode = false;
+volatile bool b_sam_ba_interface_usart = false;
+
+/* Pulse generation counters to keep track of the time remaining for each pulse type */
+#define TX_RX_LED_PULSE_PERIOD 100
+volatile uint16_t txLEDPulse = 0; // time remaining for Tx LED pulse
+volatile uint16_t rxLEDPulse = 0; // time remaining for Rx LED pulse
+
+void sam_ba_monitor_init(uint8_t com_interface)
+{
+	#if SAM_BA_INTERFACE == SAM_BA_UART_ONLY  ||  SAM_BA_INTERFACE == SAM_BA_BOTH_INTERFACES
+	//Selects the requested interface for future actions
+	if (com_interface == SAM_BA_INTERFACE_USART)
+	{
+		ptr_monitor_if = (t_monitor_if*) &uart_if;
+		b_sam_ba_interface_usart = true;
+	}
+	#endif
+	#if SAM_BA_INTERFACE == SAM_BA_USBCDC_ONLY  ||  SAM_BA_INTERFACE == SAM_BA_BOTH_INTERFACES
+	if (com_interface == SAM_BA_INTERFACE_USBCDC)
+	{
+		ptr_monitor_if = (t_monitor_if*) &usbcdc_if;
+	}
+	#endif
+}
+
+/*
+* Central SAM-BA monitor putdata function using the board LEDs
+*/
+static uint32_t sam_ba_putdata(t_monitor_if* pInterface, void const* data, uint32_t length)
+{
+	uint32_t result;
+	
+	if(usbComOpen){
+		result=pInterface->putdata(data, length);
+		} else {
+		result = 0;
+	}
+
+	//LEDTX_on();
+	//txLEDPulse = TX_RX_LED_PULSE_PERIOD;
+
+	return result;
+}
+
+/*
+* Central SAM-BA monitor getdata function using the board LEDs
+*/
+static uint32_t sam_ba_getdata(t_monitor_if* pInterface, void* data, uint32_t length)
+{
+	uint32_t result ;
+
+	result=pInterface->getdata(data, length);
+
+	if (result)
+	{
+		//LEDRX_on();
+		//rxLEDPulse = TX_RX_LED_PULSE_PERIOD;
+	}
+
+	return result;
+}
+
+/*
+* Central SAM-BA monitor putdata function using the board LEDs
+*/
+static uint32_t sam_ba_putdata_xmd(t_monitor_if* pInterface, void const* data, uint32_t length)
+{
+	uint32_t result ;
+
+	result=pInterface->putdata_xmd(data, length);
+
+	//LEDTX_on();
+	//txLEDPulse = TX_RX_LED_PULSE_PERIOD;
+
+	return result;
+}
+
+/*
+* Central SAM-BA monitor getdata function using the board LEDs
+*/
+static uint32_t sam_ba_getdata_xmd(t_monitor_if* pInterface, void* data, uint32_t length)
+{
+	uint32_t result ;
+
+	result=pInterface->getdata_xmd(data, length);
+
+	if (result)
+	{
+		//LEDRX_on();
+		//rxLEDPulse = TX_RX_LED_PULSE_PERIOD;
+	}
+
+	return result;
+}
+
+/**
+* \brief This function allows data emission by USART
+*
+* \param *data  Data pointer
+* \param length Length of the data
+*/
+void sam_ba_putdata_term(uint8_t* data, uint32_t length)
+{
+	uint8_t temp, buf[12], *data_ascii;
+	uint32_t i, int_value;
+
+	if (b_terminal_mode)
+	{
+		if (length == 4)
+		int_value = *(uint32_t *) data;
+		else if (length == 2)
+		int_value = *(uint16_t *) data;
+		else
+		int_value = *(uint8_t *) data;
+
+		data_ascii = buf + 2;
+		data_ascii += length * 2 - 1;
+
+		for (i = 0; i < length * 2; i++)
+		{
+			temp = (uint8_t) (int_value & 0xf);
+
+			if (temp <= 0x9)
+			*data_ascii = temp | 0x30;
+			else
+			*data_ascii = temp + 0x37;
+
+			int_value >>= 4;
+			data_ascii--;
+		}
+		buf[0] = '0';
+		buf[1] = 'x';
+		buf[length * 2 + 2] = '\n';
+		buf[length * 2 + 3] = '\r';
+		sam_ba_putdata(ptr_monitor_if, buf, length * 2 + 4);
+	}
+	else
+	sam_ba_putdata(ptr_monitor_if, data, length);
+	return;
+}
+
+volatile uint32_t sp;
+void call_applet(uint32_t address)
+{
+	uint32_t app_start_address;
+
+	__disable_irq();
+
+	sp = __get_MSP();
+
+	/* Rebase the Stack Pointer */
+	__set_MSP(*(uint32_t *) address);
+
+	/* Load the Reset Handler address of the application */
+	app_start_address = *(uint32_t *)(address + 4);
+
+	/* Jump to application Reset Handler in the application */
+	asm("bx %0"::"r"(app_start_address));
+}
+
+uint32_t current_number;
+uint32_t i, length;
+uint8_t command, *ptr_data, *ptr, data[SIZEBUFMAX];
+uint8_t j;
+uint32_t u32tmp;
+
+uint32_t PAGE_SIZE, PAGES, MAX_FLASH;
+
+// Prints a 32-bit integer in hex.
+static void put_uint32(uint32_t n)
+{
+	char buff[8];
+	int i;
+	for (i=0; i<8; i++)
+	{
+		int d = n & 0XF;
+		n = (n >> 4);
+
+		buff[7-i] = d > 9 ? 'A' + d - 10 : '0' + d;
+	}
+	sam_ba_putdata( ptr_monitor_if, buff, 8);
+}
+
+uint32_t tick = 0;
+uint8_t data_out[3] = {12, 48, 64};
+
+static void sam_ba_monitor_loop(void)
+{
+	// get bytes, handle.. 
+	length = sam_ba_getdata(ptr_monitor_if, data, SIZEBUFMAX);
+	if(length > 0 && !usbComOpen){
+		usbComOpen = 1;
+	}
+	
+	// reply
+	sam_ba_putdata(ptr_monitor_if, data, length);
+	
+	// dirt nasty heartbeat
+	if(!(tick % 100000)){
+		sam_ba_putdata(ptr_monitor_if, &data_out, 3);
+	}
+	tick ++;
+	
+}
+
+void sam_ba_monitor_sys_tick(void)
+{
+	/* Check whether the TX or RX LED one-shot period has elapsed.  if so, turn off the LED */
+	/*
+	if (txLEDPulse && !(--txLEDPulse))
+	LEDTX_off();
+	if (rxLEDPulse && !(--rxLEDPulse))
+	LEDRX_off();
+	*/
+}
+
+/**
+* \brief This function starts the SAM-BA monitor.
+*/
+void sam_ba_monitor_run(void)
+{
+	uint32_t pageSizes[] = { 8, 16, 32, 64, 128, 256, 512, 1024 };
+	PAGE_SIZE = pageSizes[NVMCTRL->PARAM.bit.PSZ];
+	PAGES = NVMCTRL->PARAM.bit.NVMP;
+	MAX_FLASH = PAGE_SIZE * PAGES;
+
+	ptr_data = NULL;
+	command = 'z';
+	while (1)
+	{
+		sam_ba_monitor_loop();
+	}
+}
diff --git a/embedded/mkrouter-v06/mkrouter-v06/sam_ba_monitor.h b/embedded/mkrouter-v06/mkrouter-v06/sam_ba_monitor.h
new file mode 100644
index 0000000000000000000000000000000000000000..6cfa4db0358f6231cbc70cf1439b3a4e049a4326
--- /dev/null
+++ b/embedded/mkrouter-v06/mkrouter-v06/sam_ba_monitor.h
@@ -0,0 +1,72 @@
+/*
+  Copyright (c) 2015 Arduino LLC.  All right reserved.
+  Copyright (c) 2015 Atmel Corporation/Thibaut VIARD.  All right reserved.
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  This library 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 Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+
+#ifndef _MONITOR_SAM_BA_H_
+#define _MONITOR_SAM_BA_H_
+
+#define SAM_BA_VERSION              "2.0"
+
+/* Enable the interfaces to save code size */
+#define SAM_BA_BOTH_INTERFACES      0
+#define SAM_BA_UART_ONLY            1
+#define SAM_BA_USBCDC_ONLY          2
+
+#ifndef SAM_BA_INTERFACE
+#define SAM_BA_INTERFACE    SAM_BA_BOTH_INTERFACES
+#endif
+
+/* Selects USB as the communication interface of the monitor */
+#define SAM_BA_INTERFACE_USBCDC     0
+/* Selects USART as the communication interface of the monitor */
+#define SAM_BA_INTERFACE_USART      1
+
+/* Selects USB as the communication interface of the monitor */
+#define SIZEBUFMAX                  64
+
+/**
+ * \brief Initialize the monitor
+ *
+ */
+void sam_ba_monitor_init(uint8_t com_interface);
+
+/**
+ * \brief System tick function of the SAM-BA Monitor
+ *
+ */
+void sam_ba_monitor_sys_tick(void);
+
+/**
+ * \brief Main function of the SAM-BA Monitor
+ *
+ */
+void sam_ba_monitor_run(void);
+
+/**
+ * \brief
+ *
+ */
+void sam_ba_putdata_term(uint8_t* data, uint32_t length);
+
+/**
+ * \brief
+ *
+ */
+void call_applet(uint32_t address);
+
+#endif // _MONITOR_SAM_BA_H_
diff --git a/embedded/mkrouter-v06/mkrouter-v06/sam_ba_serial.c b/embedded/mkrouter-v06/mkrouter-v06/sam_ba_serial.c
new file mode 100644
index 0000000000000000000000000000000000000000..6b02b285000f7f35e0c003f7afe6c9783961bd62
--- /dev/null
+++ b/embedded/mkrouter-v06/mkrouter-v06/sam_ba_serial.c
@@ -0,0 +1,529 @@
+/*
+  Copyright (c) 2015 Arduino LLC.  All right reserved.
+  Copyright (c) 2015 Atmel Corporation/Thibaut VIARD.  All right reserved.
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  This library 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 Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+
+#include <sam.h>
+#include "board_definitions.h"
+#include "sam_ba_serial.h"
+#include "board_driver_serial.h"
+
+/* Local reference to current Usart instance in use with this driver */
+//struct usart_module usart_sam_ba;
+
+/* Variable to let the main task select the appropriate communication interface */
+volatile uint8_t b_sharp_received;
+
+/* RX and TX Buffers + rw pointers for each buffer */
+volatile uint8_t buffer_rx_usart[USART_BUFFER_SIZE];
+
+volatile uint8_t idx_rx_read;
+volatile uint8_t idx_rx_write;
+
+volatile uint8_t buffer_tx_usart[USART_BUFFER_SIZE];
+
+volatile uint8_t idx_tx_read;
+volatile uint8_t idx_tx_write;
+
+/* Test for timeout in AT91F_GetChar */
+uint8_t error_timeout;
+uint16_t size_of_data;
+uint8_t mode_of_transfer;
+
+#define BOOT_USART_PAD(n) BOOT_USART_PAD##n
+
+#define GPIO_PIN(n) (((n)&0x1Fu) << 0)
+#define GPIO_PORT(n) ((n) >> 5)
+
+/**
+ * \brief Open the given USART
+ */
+void serial_open(void)
+{
+	uint32_t port;
+	uint32_t pin;
+	  
+	GCLK->PCHCTRL[BOOT_GCLK_ID_CORE].reg = GCLK_PCHCTRL_GEN_GCLK0_Val | (1 << GCLK_PCHCTRL_CHEN_Pos);
+	GCLK->PCHCTRL[BOOT_GCLK_ID_SLOW].reg = GCLK_PCHCTRL_GEN_GCLK3_Val | (1 << GCLK_PCHCTRL_CHEN_Pos);
+	
+	MCLK->BOOK_USART_MASK.reg |= BOOT_USART_BUS_CLOCK_INDEX ;
+	
+	/* Configure the port pins for SERCOM_USART */
+	if (BOOT_USART_PAD0 != PINMUX_UNUSED)
+  {
+		/* Mask 6th bit in pin number to check whether it is greater than 32 i.e., PORTB pin */
+		port = (BOOT_USART_PAD0 & 0x200000) >> 21;
+		pin = (BOOT_USART_PAD0 >> 16);
+		PORT->Group[port].PINCFG[(pin - (port*32))].bit.PMUXEN = 1;
+		PORT->Group[port].PMUX[(pin - (port*32))/2].reg &= ~(0xF << (4 * (pin & 0x01u)));
+		PORT->Group[port].PMUX[(pin - (port*32))/2].reg |= (BOOT_USART_PAD0 & 0xFF) << (4 * (pin & 0x01u));
+	}
+
+	if (BOOT_USART_PAD1 != PINMUX_UNUSED)
+  {
+		/* Mask 6th bit in pin number to check whether it is greater than 32 i.e., PORTB pin */
+		port = (BOOT_USART_PAD1 & 0x200000) >> 21;
+		pin = BOOT_USART_PAD1 >> 16;
+		PORT->Group[port].PINCFG[(pin - (port*32))].bit.PMUXEN = 1;
+		PORT->Group[port].PMUX[(pin - (port*32))/2].reg &= ~(0xF << (4 * (pin & 0x01u)));
+		PORT->Group[port].PMUX[(pin - (port*32))/2].reg |= (BOOT_USART_PAD1 & 0xFF) << (4 * (pin & 0x01u));
+	}
+
+	if (BOOT_USART_PAD2 != PINMUX_UNUSED)
+  {
+		/* Mask 6th bit in pin number to check whether it is greater than 32 i.e., PORTB pin */
+		port = (BOOT_USART_PAD2 & 0x200000) >> 21;
+		pin = BOOT_USART_PAD2 >> 16;
+		PORT->Group[port].PINCFG[(pin - (port*32))].bit.PMUXEN = 1;
+		PORT->Group[port].PMUX[(pin - (port*32))/2].reg &= ~(0xF << (4 * (pin & 0x01u)));
+		PORT->Group[port].PMUX[(pin - (port*32))/2].reg |= (BOOT_USART_PAD2 & 0xFF) << (4 * (pin & 0x01u));
+	}
+
+	if (BOOT_USART_PAD3 != PINMUX_UNUSED)
+  {
+		/* Mask 6th bit in pin number to check whether it is greater than 32 i.e., PORTB pin */
+		port = (BOOT_USART_PAD3 & 0x200000) >> 21;
+		pin = BOOT_USART_PAD3 >> 16;
+		PORT->Group[port].PINCFG[(pin - (port*32))].bit.PMUXEN = 1;
+		PORT->Group[port].PMUX[(pin - (port*32))/2].reg &= ~(0xF << (4 * (pin & 0x01u)));
+		PORT->Group[port].PMUX[(pin - (port*32))/2].reg |= (BOOT_USART_PAD3 & 0xFF) << (4 * (pin & 0x01u));
+	}
+
+	/* Baud rate 115200 - clock 48MHz -> BAUD value-63018 */
+	uart_basic_init(BOOT_USART_MODULE, 63018, BOOT_USART_PAD_SETTINGS);
+
+	//Initialize flag
+	b_sharp_received = false;
+	idx_rx_read = 0;
+	idx_rx_write = 0;
+	idx_tx_read = 0;
+	idx_tx_write = 0;
+
+	error_timeout = 0;
+}
+
+/**
+ * \brief Close communication line
+ */
+void serial_close(void)
+{
+	uart_disable(BOOT_USART_MODULE);
+}
+
+/**
+ * \brief Puts a byte on usart line
+ * The type int is used to support printf redirection from compiler LIB.
+ *
+ * \param value      Value to put
+ *
+ * \return \c 1 if function was successfully done, otherwise \c 0.
+ */
+int serial_putc(int value)
+{	
+	uart_write_byte(BOOT_USART_MODULE, (uint8_t)value);
+	return 1;
+}
+
+int serial_getc(void)
+{
+	uint16_t retval;
+	//Wait until input buffer is filled
+	while(!(serial_is_rx_ready()));
+	retval = (uint16_t)uart_read_byte(BOOT_USART_MODULE);
+	//usart_read_wait(&usart_sam_ba, &retval);
+	return (int)retval;
+
+}
+
+int serial_sharp_received(void)
+{
+	if (serial_is_rx_ready())
+  {
+		if (serial_getc() == SHARP_CHARACTER)
+			return (true);
+	}
+	return (false);
+}
+
+bool serial_is_rx_ready(void)
+{
+	return (BOOT_USART_MODULE->USART.INTFLAG.reg & SERCOM_USART_INTFLAG_RXC);
+}
+
+int serial_readc(void)
+{
+	int retval;
+	retval = buffer_rx_usart[idx_rx_read];
+	idx_rx_read = (idx_rx_read + 1) & (USART_BUFFER_SIZE - 1);
+	return (retval);
+}
+
+//Send given data (polling)
+uint32_t serial_putdata(void const* data, uint32_t length)
+{
+	uint32_t i;
+	uint8_t* ptrdata;
+	ptrdata = (uint8_t*) data;
+	for (i = 0; i < length; i++)
+  {
+		serial_putc(*ptrdata);
+		ptrdata++;
+	}
+	return (i);
+}
+
+//Get data from comm. device
+uint32_t serial_getdata(void* data, uint32_t length)
+{
+	uint8_t* ptrdata;
+	ptrdata = (uint8_t*) data;
+	*ptrdata = serial_getc();
+	return (1);
+}
+
+static const uint16_t crc16Table[256]=
+{
+	0x0000,0x1021,0x2042,0x3063,0x4084,0x50a5,0x60c6,0x70e7,
+	0x8108,0x9129,0xa14a,0xb16b,0xc18c,0xd1ad,0xe1ce,0xf1ef,
+	0x1231,0x0210,0x3273,0x2252,0x52b5,0x4294,0x72f7,0x62d6,
+	0x9339,0x8318,0xb37b,0xa35a,0xd3bd,0xc39c,0xf3ff,0xe3de,
+	0x2462,0x3443,0x0420,0x1401,0x64e6,0x74c7,0x44a4,0x5485,
+	0xa56a,0xb54b,0x8528,0x9509,0xe5ee,0xf5cf,0xc5ac,0xd58d,
+	0x3653,0x2672,0x1611,0x0630,0x76d7,0x66f6,0x5695,0x46b4,
+	0xb75b,0xa77a,0x9719,0x8738,0xf7df,0xe7fe,0xd79d,0xc7bc,
+	0x48c4,0x58e5,0x6886,0x78a7,0x0840,0x1861,0x2802,0x3823,
+	0xc9cc,0xd9ed,0xe98e,0xf9af,0x8948,0x9969,0xa90a,0xb92b,
+	0x5af5,0x4ad4,0x7ab7,0x6a96,0x1a71,0x0a50,0x3a33,0x2a12,
+	0xdbfd,0xcbdc,0xfbbf,0xeb9e,0x9b79,0x8b58,0xbb3b,0xab1a,
+	0x6ca6,0x7c87,0x4ce4,0x5cc5,0x2c22,0x3c03,0x0c60,0x1c41,
+	0xedae,0xfd8f,0xcdec,0xddcd,0xad2a,0xbd0b,0x8d68,0x9d49,
+	0x7e97,0x6eb6,0x5ed5,0x4ef4,0x3e13,0x2e32,0x1e51,0x0e70,
+	0xff9f,0xefbe,0xdfdd,0xcffc,0xbf1b,0xaf3a,0x9f59,0x8f78,
+	0x9188,0x81a9,0xb1ca,0xa1eb,0xd10c,0xc12d,0xf14e,0xe16f,
+	0x1080,0x00a1,0x30c2,0x20e3,0x5004,0x4025,0x7046,0x6067,
+	0x83b9,0x9398,0xa3fb,0xb3da,0xc33d,0xd31c,0xe37f,0xf35e,
+	0x02b1,0x1290,0x22f3,0x32d2,0x4235,0x5214,0x6277,0x7256,
+	0xb5ea,0xa5cb,0x95a8,0x8589,0xf56e,0xe54f,0xd52c,0xc50d,
+	0x34e2,0x24c3,0x14a0,0x0481,0x7466,0x6447,0x5424,0x4405,
+	0xa7db,0xb7fa,0x8799,0x97b8,0xe75f,0xf77e,0xc71d,0xd73c,
+	0x26d3,0x36f2,0x0691,0x16b0,0x6657,0x7676,0x4615,0x5634,
+	0xd94c,0xc96d,0xf90e,0xe92f,0x99c8,0x89e9,0xb98a,0xa9ab,
+	0x5844,0x4865,0x7806,0x6827,0x18c0,0x08e1,0x3882,0x28a3,
+	0xcb7d,0xdb5c,0xeb3f,0xfb1e,0x8bf9,0x9bd8,0xabbb,0xbb9a,
+	0x4a75,0x5a54,0x6a37,0x7a16,0x0af1,0x1ad0,0x2ab3,0x3a92,
+	0xfd2e,0xed0f,0xdd6c,0xcd4d,0xbdaa,0xad8b,0x9de8,0x8dc9,
+	0x7c26,0x6c07,0x5c64,0x4c45,0x3ca2,0x2c83,0x1ce0,0x0cc1,
+	0xef1f,0xff3e,0xcf5d,0xdf7c,0xaf9b,0xbfba,0x8fd9,0x9ff8,
+	0x6e17,0x7e36,0x4e55,0x5e74,0x2e93,0x3eb2,0x0ed1,0x1ef0
+};
+
+//*----------------------------------------------------------------------------
+//* \brief Compute the CRC
+//*----------------------------------------------------------------------------
+unsigned short serial_add_crc(char ptr, unsigned short crc)
+{
+	return (crc << 8) ^ crc16Table[((crc >> 8) ^ ptr) & 0xff];
+}
+
+//*----------------------------------------------------------------------------
+//* \brief
+//*----------------------------------------------------------------------------
+static uint16_t getbytes(uint8_t *ptr_data, uint16_t length)
+{
+	uint16_t crc = 0;
+	uint16_t cpt;
+	uint8_t c;
+
+	for (cpt = 0; cpt < length; ++cpt)
+  {
+		c = serial_getc();
+		if (error_timeout)
+			return 1;
+		crc = serial_add_crc(c, crc);
+		//crc = (crc << 8) ^ xcrc16tab[(crc>>8) ^ c];
+		if (size_of_data || mode_of_transfer)
+    {
+			*ptr_data++ = c;
+			if (length == PKTLEN_128)
+				size_of_data--;
+		}
+	}
+
+	return crc;
+}
+
+//*----------------------------------------------------------------------------
+//* \brief Used by Xup to send packets.
+//*----------------------------------------------------------------------------
+static int putPacket(uint8_t *tmppkt, uint8_t sno)
+{
+	uint32_t i;
+	uint16_t chksm;
+	uint8_t data;
+
+	chksm = 0;
+
+	serial_putc(SOH);
+
+	serial_putc(sno);
+	serial_putc((uint8_t) ~(sno));
+
+	for (i = 0; i < PKTLEN_128; i++)
+  {
+		if (size_of_data || mode_of_transfer)
+    {
+			data = *tmppkt++;
+			size_of_data--;
+		}
+    else
+			data = 0x00;
+
+		serial_putc(data);
+
+		//chksm = (chksm<<8) ^ xcrc16tab[(chksm>>8)^data];
+		chksm = serial_add_crc(data, chksm);
+	}
+
+	/* An "endian independent way to extract the CRC bytes. */
+	serial_putc((uint8_t) (chksm >> 8));
+	serial_putc((uint8_t) chksm);
+
+	return (serial_getc()); /* Wait for ack */
+}
+
+//*----------------------------------------------------------------------------
+//* \brief Called when a transfer from target to host is being made (considered
+//*        an upload).
+//*----------------------------------------------------------------------------
+//Send given data (polling) using xmodem (if necessary)
+uint32_t serial_putdata_xmd(void const* data, uint32_t length)
+{
+	uint8_t c, sno = 1;
+	uint8_t done;
+	uint8_t * ptr_data = (uint8_t *) data;
+	error_timeout = 0;
+	if (!length)
+		mode_of_transfer = 1;
+	else
+  {
+		size_of_data = length;
+		mode_of_transfer = 0;
+	}
+
+	if (length & (PKTLEN_128 - 1))
+  {
+		length += PKTLEN_128;
+		length &= ~(PKTLEN_128 - 1);
+	}
+
+	/* Startup synchronization... */
+	/* Wait to receive a NAK or 'C' from receiver. */
+	done = 0;
+	while (!done) {
+		c = (uint8_t) serial_getc();
+		if (error_timeout)
+    { // Test for timeout in serial_getc
+			error_timeout = 0;
+			c = (uint8_t) serial_getc();
+			if (error_timeout)
+      {
+				error_timeout = 0;
+				return (0);
+			}
+		}
+		switch (c)
+    {
+      case NAK:
+        done = 1;
+        // ("CSM");
+			break;
+      case 'C':
+        done = 1;
+        // ("CRC");
+			break;
+      case 'q': /* ELS addition, not part of XMODEM spec. */
+        return (0);
+      default:
+			break;
+		}
+	}
+
+	done = 0;
+	sno = 1;
+	while (!done)
+  {
+		c = (uint8_t) putPacket((uint8_t *) ptr_data, sno);
+		if (error_timeout)
+    { // Test for timeout in serial_getc
+			error_timeout = 0;
+			return (0);
+		}
+		switch (c)
+    {
+      case ACK:
+        ++sno;
+        length -= PKTLEN_128;
+        ptr_data += PKTLEN_128;
+        // ("A");
+			break;
+
+      case NAK:
+        // ("N");
+			break;
+
+      case CAN:
+      case EOT:
+      default:
+        done = 0;
+			break;
+		}
+
+		if (!length)
+    {
+			serial_putc(EOT);
+			serial_getc(); /* Flush the ACK */
+			break;
+		}
+		// ("!");
+	}
+
+	mode_of_transfer = 0;
+	// ("Xup_done.");
+	return (1);
+	//    return(0);
+}
+
+/*----------------------------------------------------------------------------
+ * \brief Used by serial_getdata_xmd to retrieve packets.
+ */
+static uint8_t getPacket(uint8_t *ptr_data, uint8_t sno)
+{
+	uint8_t seq[2];
+	uint16_t crc, xcrc;
+
+	getbytes(seq, 2);
+	xcrc = getbytes(ptr_data, PKTLEN_128);
+	if (error_timeout)
+		return (false);
+
+	/* An "endian independent way to combine the CRC bytes. */
+	crc = (uint16_t) serial_getc() << 8;
+	crc += (uint16_t) serial_getc();
+
+	if (error_timeout == 1)
+		return (false);
+
+	if ((crc != xcrc) || (seq[0] != sno) || (seq[1] != (uint8_t) (~sno)))
+  {
+		serial_putc(CAN);
+		return (false);
+	}
+
+	serial_putc(ACK);
+	return (true);
+}
+
+//*----------------------------------------------------------------------------
+//* \brief Called when a transfer from host to target is being made (considered
+//*        an download).
+//*----------------------------------------------------------------------------
+//Get data from comm. device using xmodem (if necessary)
+uint32_t serial_getdata_xmd(void* data, uint32_t length)
+{
+	uint32_t timeout;
+	char c;
+	uint8_t * ptr_data = (uint8_t *) data;
+	uint32_t b_run, nbr_of_timeout = 100;
+	uint8_t sno = 0x01;
+	uint32_t data_transfered = 0;
+
+	//Copied from legacy source code ... might need some tweaking
+	uint32_t loops_per_second = CPU_FREQUENCY/60;
+
+	error_timeout = 0;
+
+	if (length == 0)
+		mode_of_transfer = 1;
+	else
+  {
+		size_of_data = length;
+		mode_of_transfer = 0;
+	}
+
+	/* Startup synchronization... */
+	/* Continuously send NAK or 'C' until sender responds. */
+	// ("Xdown");
+	while (1)
+  {
+		serial_putc('C');
+		timeout = loops_per_second;
+		while (!(serial_is_rx_ready()) && timeout)
+			timeout--;
+		if (timeout)
+			break;
+
+		if (!(--nbr_of_timeout))
+			return (0);
+//            return -1;
+	}
+
+	b_run = true;
+	// ("Got response");
+	while (b_run != false)
+  {
+		c = (char) serial_getc();
+		if (error_timeout)
+    { // Test for timeout in serial_getc
+			error_timeout = 0;
+			return (0);
+//            return (-1);
+		}
+		switch (c)
+    {
+      case SOH: /* 128-byte incoming packet */
+        // ("O");
+        b_run = getPacket(ptr_data, sno);
+        if (error_timeout)
+        { // Test for timeout in serial_getc
+          error_timeout = 0;
+          return (0);
+  //                return (-1);
+        }
+        if (b_run == true)
+        {
+          ++sno;
+          ptr_data += PKTLEN_128;
+          data_transfered += PKTLEN_128;
+        }
+			break;
+      case EOT: // ("E");
+        serial_putc(ACK);
+        b_run = false;
+			break;
+      case CAN: // ("C");
+      case ESC: /* "X" User-invoked abort */
+      default:
+        b_run = false;
+			break;
+		}
+		// ("!");
+	}
+	mode_of_transfer = 0;
+	return (true);
+//    return(b_run);
+}
+
diff --git a/embedded/mkrouter-v06/mkrouter-v06/sam_ba_serial.h b/embedded/mkrouter-v06/mkrouter-v06/sam_ba_serial.h
new file mode 100644
index 0000000000000000000000000000000000000000..cb69f459ec4ef0bf035a8b41c247f0b681d4f192
--- /dev/null
+++ b/embedded/mkrouter-v06/mkrouter-v06/sam_ba_serial.h
@@ -0,0 +1,143 @@
+/*
+  Copyright (c) 2015 Arduino LLC.  All right reserved.
+  Copyright (c) 2015 Atmel Corporation/Thibaut VIARD.  All right reserved.
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  This library 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 Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+
+#ifndef _SAM_BA_SERIAL_H_
+#define _SAM_BA_SERIAL_H_
+
+#include <stdint.h>
+#include <stdbool.h>
+
+
+/* USART buffer size (must be a power of two) */
+#define USART_BUFFER_SIZE        (128)
+
+/* Define the default time-out value for USART. */
+#define USART_DEFAULT_TIMEOUT    (1000)
+
+/* Xmodem related defines */
+/* CRC16  polynomial */
+#define CRC16POLY                (0x1021)
+
+#define SHARP_CHARACTER          '#'
+
+/* X/Ymodem protocol: */
+#define SOH                      (0x01)
+//#define STX                    (0x02)
+#define EOT                      (0x04)
+#define ACK                      (0x06)
+#define NAK                      (0x15)
+#define CAN                      (0x18)
+#define ESC                      (0x1b)
+
+#define PKTLEN_128               (128)
+
+
+/**
+ * \brief Open the given USART
+ */
+void serial_open(void);
+
+/**
+ * \brief Stops the USART
+ */
+void serial_close(void);
+
+/**
+ * \brief Puts a byte on usart line
+ *
+ * \param value      Value to put
+ *
+ * \return \c 1 if function was successfully done, otherwise \c 0.
+ */
+int serial_putc(int value);
+
+/**
+ * \brief Waits and gets a value on usart line
+ *
+ * \return value read on usart line
+ */
+int serial_getc(void);
+
+/**
+ * \brief Returns true if the SAM-BA Uart received the sharp char
+ *
+ * \return Returns true if the SAM-BA Uart received the sharp char
+ */
+int serial_sharp_received(void);
+
+/**
+ * \brief This function checks if a character has been received on the usart line
+ *
+ * \return \c 1 if a byte is ready to be read.
+ */
+bool serial_is_rx_ready(void);
+
+/**
+ * \brief Gets a value on usart line
+ *
+ * \return value read on usart line
+ */
+int serial_readc(void);
+
+/**
+ * \brief Send buffer on usart line
+ *
+ * \param data pointer
+ * \param number of data to send
+ * \return number of data sent
+ */
+uint32_t serial_putdata(void const* data, uint32_t length); //Send given data (polling)
+
+/**
+ * \brief Gets data from usart line
+ *
+ * \param data pointer
+ * \param number of data to get
+ * \return value read on usart line
+ */
+uint32_t serial_getdata(void* data, uint32_t length); //Get data from comm. device
+
+/**
+ * \brief Send buffer on usart line using Xmodem protocol
+ *
+ * \param data pointer
+ * \param number of data to send
+ * \return number of data sent
+ */
+uint32_t serial_putdata_xmd(void const* data, uint32_t length); //Send given data (polling) using xmodem (if necessary)
+
+/**
+ * \brief Gets data from usart line using Xmodem protocol
+ *
+ * \param data pointer
+ * \param number of data to get
+ * \return value read on usart line
+ */
+uint32_t serial_getdata_xmd(void* data, uint32_t length); //Get data from comm. device using xmodem (if necessary)
+
+/**
+ * \brief Compute the CRC
+ *
+ * \param Char to add to CRC
+ * \param Previous CRC
+ * \return The new computed CRC
+ */
+unsigned short serial_add_crc(char c, unsigned short crc);
+
+#endif // _SAM_BA_SERIAL_H_
diff --git a/embedded/mkrouter-v06/mkrouter-v06/sam_ba_usb.c b/embedded/mkrouter-v06/mkrouter-v06/sam_ba_usb.c
new file mode 100644
index 0000000000000000000000000000000000000000..068b81d8b6cc1bb0d79f7d18998617b01a597dbb
--- /dev/null
+++ b/embedded/mkrouter-v06/mkrouter-v06/sam_ba_usb.c
@@ -0,0 +1,436 @@
+/*
+  Copyright (c) 2015 Arduino LLC.  All right reserved.
+  Copyright (c) 2015 Atmel Corporation/Thibaut VIARD.  All right reserved.
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  This library 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 Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+
+#include <stdint.h>
+#include <string.h>
+#include "board_definitions.h"
+#include "sam_ba_usb.h"
+#include "board_driver_usb.h"
+#include "sam_ba_cdc.h"
+
+/* This data array will be copied into SRAM as its length is inferior to 64 bytes,
+ * and so can stay in flash.
+ */
+static __attribute__((__aligned__(4)))
+const char devDescriptor[] =
+{
+  /* Device descriptor */
+  0x12,   // bLength
+  0x01,   // bDescriptorType
+  0x00,   // bcdUSB L
+  0x02,   // bcdUSB H
+  0x02,   // bDeviceClass:    CDC class code
+  0x00,   // bDeviceSubclass: CDC class sub code
+  0x00,   // bDeviceProtocol: CDC Device protocol
+  0x40,   // bMaxPacketSize0
+  USB_VID_LOW,   // idVendor L
+  USB_VID_HIGH,   // idVendor H
+  USB_PID_LOW,   // idProduct L
+  USB_PID_HIGH,  // idProduct H
+  0x00,   // bcdDevice L, here matching SAM-BA version
+  0x02,   // bcdDevice H
+  STRING_INDEX_MANUFACTURER,   // iManufacturer
+  STRING_INDEX_PRODUCT,        // iProduct
+  0x00,   // SerialNumber, should be based on product unique ID
+  0x01    // bNumConfigs
+};
+
+/* This data array will be consumed directly by USB_Write() and must be in SRAM.
+ * We cannot send data from product internal flash.
+ */
+static __attribute__((__aligned__(4)))
+char cfgDescriptor[] =
+{
+  /* ============== CONFIGURATION 1 =========== */
+  /* Configuration 1 descriptor */
+  0x09,   // CbLength
+  0x02,   // CbDescriptorType
+  0x43,   // CwTotalLength 2 EP + Control
+  0x00,
+  0x02,   // CbNumInterfaces
+  0x01,   // CbConfigurationValue
+  0x00,   // CiConfiguration
+  0x80,   // CbmAttributes Bus powered without remote wakeup: 0x80, Self powered without remote wakeup: 0xc0
+  0x32,   // CMaxPower, report using 100mA, enough for a bootloader
+
+  /* Communication Class Interface Descriptor Requirement */
+  0x09, // bLength
+  0x04, // bDescriptorType
+  0x00, // bInterfaceNumber
+  0x00, // bAlternateSetting
+  0x01, // bNumEndpoints
+  0x02, // bInterfaceClass
+  0x02, // bInterfaceSubclass
+  0x00, // bInterfaceProtocol
+  0x00, // iInterface
+
+  /* Header Functional Descriptor */
+  0x05, // bFunction Length
+  0x24, // bDescriptor type: CS_INTERFACE
+  0x00, // bDescriptor subtype: Header Func Desc
+  0x10, // bcdCDC:1.1
+  0x01,
+
+  /* ACM Functional Descriptor */
+  0x04, // bFunctionLength
+  0x24, // bDescriptor Type: CS_INTERFACE
+  0x02, // bDescriptor Subtype: ACM Func Desc
+  0x00, // bmCapabilities
+
+  /* Union Functional Descriptor */
+  0x05, // bFunctionLength
+  0x24, // bDescriptorType: CS_INTERFACE
+  0x06, // bDescriptor Subtype: Union Func Desc
+  0x00, // bMasterInterface: Communication Class Interface
+  0x01, // bSlaveInterface0: Data Class Interface
+
+  /* Call Management Functional Descriptor */
+  0x05, // bFunctionLength
+  0x24, // bDescriptor Type: CS_INTERFACE
+  0x01, // bDescriptor Subtype: Call Management Func Desc
+  0x00, // bmCapabilities: D1 + D0
+  0x01, // bDataInterface: Data Class Interface 1
+
+  /* Endpoint 1 descriptor */
+  0x07,   // bLength
+  0x05,   // bDescriptorType
+  0x83,   // bEndpointAddress, Endpoint 03 - IN
+  0x03,   // bmAttributes      INT
+  0x08,   // wMaxPacketSize
+  0x00,
+  0xFF,   // bInterval
+
+  /* Data Class Interface Descriptor Requirement */
+  0x09, // bLength
+  0x04, // bDescriptorType
+  0x01, // bInterfaceNumber
+  0x00, // bAlternateSetting
+  0x02, // bNumEndpoints
+  0x0A, // bInterfaceClass
+  0x00, // bInterfaceSubclass
+  0x00, // bInterfaceProtocol
+  0x00, // iInterface
+
+  /* First alternate setting */
+  /* Endpoint 1 descriptor */
+  0x07,   // bLength
+  0x05,   // bDescriptorType
+  0x81,   // bEndpointAddress, Endpoint 01 - IN
+  0x02,   // bmAttributes      BULK
+  USB_EP_IN_SIZE,   // wMaxPacketSize
+  0x00,
+  0x00,   // bInterval
+
+  /* Endpoint 2 descriptor */
+  0x07,   // bLength
+  0x05,   // bDescriptorType
+  0x02,   // bEndpointAddress, Endpoint 02 - OUT
+  0x02,   // bmAttributes      BULK
+  USB_EP_OUT_SIZE,   // wMaxPacketSize
+  0x00,
+  0x00    // bInterval
+};
+
+#ifndef STRING_MANUFACTURER
+#  define STRING_MANUFACTURER "Arduino LLC"
+#endif
+
+#ifndef STRING_PRODUCT
+#  define STRING_PRODUCT "Arduino Zero"
+#endif
+
+USB_CDC sam_ba_cdc;
+
+/*----------------------------------------------------------------------------
+ * \brief This function is a callback invoked when a SETUP packet is received
+ */
+void sam_ba_usb_CDC_Enumerate(P_USB_CDC pCdc)
+{
+  Usb *pUsb = pCdc->pUsb;
+  static volatile uint8_t bmRequestType, bRequest, dir;
+  static volatile uint16_t wValue, wIndex, wLength, wStatus;
+
+  /* Clear the Received Setup flag */
+  pUsb->DEVICE.DeviceEndpoint[0].EPINTFLAG.reg = USB_DEVICE_EPINTFLAG_RXSTP;
+
+  /* Read the USB request parameters */
+  bmRequestType = udd_ep_out_cache_buffer[0][0];
+  bRequest      = udd_ep_out_cache_buffer[0][1];
+  wValue        = (udd_ep_out_cache_buffer[0][2] & 0xFF);
+  wValue       |= (udd_ep_out_cache_buffer[0][3] << 8);
+  wIndex        = (udd_ep_out_cache_buffer[0][4] & 0xFF);
+  wIndex       |= (udd_ep_out_cache_buffer[0][5] << 8);
+  wLength       = (udd_ep_out_cache_buffer[0][6] & 0xFF);
+  wLength      |= (udd_ep_out_cache_buffer[0][7] << 8);
+
+  /* Clear the Bank 0 ready flag on Control OUT */
+  pUsb->DEVICE.DeviceEndpoint[0].EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_BK0RDY;
+
+  /* Handle supported standard device request Cf Table 9-3 in USB specification Rev 1.1 */
+  switch ((bRequest << 8) | bmRequestType)
+  {
+    case STD_GET_DESCRIPTOR:
+      if (wValue>>8 == STD_GET_DESCRIPTOR_DEVICE)
+      {
+        /* Return Device Descriptor */
+        USB_Write(pCdc->pUsb, devDescriptor, SAM_BA_MIN(sizeof(devDescriptor), wLength), USB_EP_CTRL);
+      }
+      else if (wValue>>8 == STD_GET_DESCRIPTOR_CONFIGURATION)
+      {
+        /* Return Configuration Descriptor */
+        USB_Write(pCdc->pUsb, cfgDescriptor, SAM_BA_MIN(sizeof(cfgDescriptor), wLength), USB_EP_CTRL);
+      }
+      else if (wValue>>8 == STD_GET_DESCRIPTOR_STRING)
+      {
+        switch ( wValue & 0xff )
+        {
+          case STRING_INDEX_LANGUAGES: {
+            uint16_t STRING_LANGUAGE[2] = { (STD_GET_DESCRIPTOR_STRING<<8) | 4, 0x0409 };
+
+            USB_Write(pCdc->pUsb, (const char*)STRING_LANGUAGE, SAM_BA_MIN(sizeof(STRING_LANGUAGE), wLength), USB_EP_CTRL);
+          }
+          break;
+
+          case STRING_INDEX_MANUFACTURER:
+            USB_SendString(pCdc->pUsb, STRING_MANUFACTURER, wLength );
+          break;
+
+          case STRING_INDEX_PRODUCT:
+            USB_SendString(pCdc->pUsb, STRING_PRODUCT, wLength );
+          break;
+          default:
+            /* Stall the request */
+            USB_SendStall(pUsb, true);
+          break;
+        }
+      }
+      else
+      {
+        /* Stall the request */
+        USB_SendStall(pUsb, true);
+      }
+    break;
+
+    case STD_SET_ADDRESS:
+      /* Send ZLP */
+      USB_SendZlp(pUsb);
+      /* Set device address to the newly received address from host */
+      USB_SetAddress(pCdc->pUsb, wValue);
+    break;
+
+    case STD_SET_CONFIGURATION:
+      /* Store configuration */
+      pCdc->currentConfiguration = (uint8_t)wValue;
+
+      /* Send ZLP */
+      USB_SendZlp(pUsb);
+
+      /* Configure the 3 needed endpoints */
+      USB_Configure(pUsb);
+    break;
+
+    case STD_GET_CONFIGURATION:
+      /* Return current configuration value */
+      USB_Write(pCdc->pUsb, (char *) &(pCdc->currentConfiguration), sizeof(pCdc->currentConfiguration), USB_EP_CTRL);
+    break;
+
+    case STD_GET_STATUS_ZERO:
+      wStatus = 0;
+      USB_Write(pCdc->pUsb, (char *) &wStatus, sizeof(wStatus), USB_EP_CTRL);
+    break;
+
+    case STD_GET_STATUS_INTERFACE:
+      wStatus = 0;
+      USB_Write(pCdc->pUsb, (char *) &wStatus, sizeof(wStatus), USB_EP_CTRL);
+    break;
+
+    case STD_GET_STATUS_ENDPOINT:
+      wStatus = 0;
+      dir = wIndex & 80;
+      wIndex &= 0x0F;
+      if (wIndex <= 3)
+      {
+        if (dir)
+        {
+          wStatus = (pUsb->DEVICE.DeviceEndpoint[wIndex].EPSTATUS.reg & USB_DEVICE_EPSTATUSSET_STALLRQ1) ? 1 : 0;
+        }
+        else
+        {
+          wStatus = (pUsb->DEVICE.DeviceEndpoint[wIndex].EPSTATUS.reg & USB_DEVICE_EPSTATUSSET_STALLRQ0) ? 1 : 0;
+        }
+        /* Return current status of endpoint */
+        USB_Write(pCdc->pUsb, (char *) &wStatus, sizeof(wStatus), USB_EP_CTRL);
+      }
+      else
+      {
+        /* Stall the request */
+        USB_SendStall(pUsb, true);
+      }
+    break;
+
+    case STD_SET_FEATURE_ZERO:
+      /* Stall the request */
+      USB_SendStall(pUsb, true);
+    break;
+
+    case STD_SET_FEATURE_INTERFACE:
+      /* Send ZLP */
+      USB_SendZlp(pUsb);
+    break;
+
+    case STD_SET_FEATURE_ENDPOINT:
+      dir = wIndex & 0x80;
+      wIndex &= 0x0F;
+      if ((wValue == 0) && wIndex && (wIndex <= 3))
+      {
+        /* Set STALL request for the endpoint */
+        if (dir)
+        {
+          pUsb->DEVICE.DeviceEndpoint[wIndex].EPSTATUSSET.reg = USB_DEVICE_EPSTATUSSET_STALLRQ1;
+        }
+        else
+        {
+          pUsb->DEVICE.DeviceEndpoint[wIndex].EPSTATUSSET.reg = USB_DEVICE_EPSTATUSSET_STALLRQ0;
+        }
+
+        /* Send ZLP */
+        USB_SendZlp(pUsb);
+      }
+      else
+      {
+        /* Stall the request */
+        USB_SendStall(pUsb, true);
+      }
+    break;
+
+    case STD_SET_INTERFACE:
+    case STD_CLEAR_FEATURE_ZERO:
+      /* Stall the request */
+      USB_SendStall(pUsb, true);
+    break;
+
+    case STD_CLEAR_FEATURE_INTERFACE:
+      /* Send ZLP */
+      USB_SendZlp(pUsb);
+    break;
+
+    case STD_CLEAR_FEATURE_ENDPOINT:
+      dir = wIndex & 0x80;
+      wIndex &= 0x0F;
+
+      if ((wValue == 0) && wIndex && (wIndex <= 3))
+      {
+        if (dir)
+        {
+          if (pUsb->DEVICE.DeviceEndpoint[wIndex].EPSTATUS.bit.STALLRQ1)
+          {
+            // Remove stall request
+            pUsb->DEVICE.DeviceEndpoint[wIndex].EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_STALLRQ1;
+            if (pUsb->DEVICE.DeviceEndpoint[wIndex].EPINTFLAG.bit.STALL1)
+            {
+              pUsb->DEVICE.DeviceEndpoint[wIndex].EPINTFLAG.reg = USB_DEVICE_EPINTFLAG_STALL1;
+              // The Stall has occurred, then reset data toggle
+              pUsb->DEVICE.DeviceEndpoint[wIndex].EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSSET_DTGLIN;
+            }
+          }
+        }
+        else
+        {
+          if (pUsb->DEVICE.DeviceEndpoint[wIndex].EPSTATUS.bit.STALLRQ0)
+          {
+            // Remove stall request
+            pUsb->DEVICE.DeviceEndpoint[wIndex].EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_STALLRQ0;
+            if (pUsb->DEVICE.DeviceEndpoint[wIndex].EPINTFLAG.bit.STALL0)
+            {
+              pUsb->DEVICE.DeviceEndpoint[wIndex].EPINTFLAG.reg = USB_DEVICE_EPINTFLAG_STALL0;
+              // The Stall has occurred, then reset data toggle
+              pUsb->DEVICE.DeviceEndpoint[wIndex].EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSSET_DTGLOUT;
+            }
+          }
+        }
+        /* Send ZLP */
+        USB_SendZlp(pUsb);
+      }
+      else
+      {
+        USB_SendStall(pUsb, true);
+      }
+    break;
+
+    // handle CDC class requests
+    case SET_LINE_CODING:
+      /* Send ZLP */
+      USB_SendZlp(pUsb);
+    break;
+
+    case GET_LINE_CODING:
+      /* Send current line coding */
+      USB_Write(pCdc->pUsb, (char *) &line_coding, SAM_BA_MIN(sizeof(usb_cdc_line_coding_t), wLength), USB_EP_CTRL);
+    break;
+
+    case SET_CONTROL_LINE_STATE:
+      /* Store the current connection */
+      pCdc->currentConnection = wValue;
+      /* Send ZLP */
+      USB_SendZlp(pUsb);
+    break;
+
+    default:
+      /* Stall the request */
+      USB_SendStall(pUsb, true);
+    break;
+  }
+}
+
+/*----------------------------------------------------------------------------
+ * \brief
+ */
+P_USB_CDC usb_init(void)
+{
+  sam_ba_cdc.pUsb = USB;
+
+  /* Initialize USB */
+  USB_Init();
+  /* Get the default CDC structure settings */
+  USB_Open(&sam_ba_cdc, sam_ba_cdc.pUsb);
+
+  return &sam_ba_cdc;
+}
+
+/*----------------------------------------------------------------------------
+ * \brief Send a USB descriptor string.
+ *
+ * The input string is plain ASCII but is sent out as UTF-16 with the correct 2-byte prefix.
+ */
+uint32_t USB_SendString(Usb *pUsb, const char* ascii_string, uint8_t maxLength)
+{
+  uint8_t string_descriptor[255]; // Max USB-allowed string length
+  uint16_t* unicode_string=(uint16_t*)(string_descriptor+2); // point on 3 bytes of descriptor
+  int resulting_length;
+
+  string_descriptor[0] = (strlen(ascii_string)<<1) + 2;
+  string_descriptor[1] = STD_GET_DESCRIPTOR_STRING;
+
+  for ( resulting_length = 1 ; *ascii_string && (resulting_length<maxLength>>1) ; resulting_length++ )
+  {
+    *unicode_string++ = (uint16_t)(*ascii_string++);
+  }
+
+  return USB_Write(pUsb, (const char*)string_descriptor, resulting_length<<1, USB_EP_CTRL);
+}
diff --git a/embedded/mkrouter-v06/mkrouter-v06/sam_ba_usb.h b/embedded/mkrouter-v06/mkrouter-v06/sam_ba_usb.h
new file mode 100644
index 0000000000000000000000000000000000000000..457fdbc097bceffe6f57b748946e0fc5f361a744
--- /dev/null
+++ b/embedded/mkrouter-v06/mkrouter-v06/sam_ba_usb.h
@@ -0,0 +1,103 @@
+/*
+  Copyright (c) 2015 Arduino LLC.  All right reserved.
+  Copyright (c) 2015 Atmel Corporation/Thibaut VIARD.  All right reserved.
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  This library 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 Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+
+#ifndef CDC_ENUMERATE_H
+#define CDC_ENUMERATE_H
+
+#include <sam.h>
+#include <stdbool.h>
+
+#define USB_EP_CTRL             (0u)
+#define USB_EP_OUT              (2u)
+#define USB_EP_OUT_SIZE         (0x40u)
+#define USB_EP_IN               (1u)
+#define USB_EP_IN_SIZE          (0x40u)
+#define USB_EP_COMM             (3u)
+#define MAX_EP                  (4u)
+
+/* USB standard request code */
+#define STD_GET_STATUS_ZERO            (0x0080u)
+#define STD_GET_STATUS_INTERFACE       (0x0081u)
+#define STD_GET_STATUS_ENDPOINT        (0x0082u)
+
+#define STD_CLEAR_FEATURE_ZERO         (0x0100u)
+#define STD_CLEAR_FEATURE_INTERFACE    (0x0101u)
+#define STD_CLEAR_FEATURE_ENDPOINT     (0x0102u)
+
+#define STD_SET_FEATURE_ZERO           (0x0300u)
+#define STD_SET_FEATURE_INTERFACE      (0x0301u)
+#define STD_SET_FEATURE_ENDPOINT       (0x0302u)
+
+#define STD_SET_ADDRESS                (0x0500u)
+#define STD_GET_DESCRIPTOR             (0x0680u)
+#define STD_SET_DESCRIPTOR             (0x0700u)
+#define STD_GET_CONFIGURATION          (0x0880u)
+#define STD_SET_CONFIGURATION          (0x0900u)
+#define STD_GET_INTERFACE              (0x0A81u)
+#define STD_SET_INTERFACE              (0x0B01u)
+#define STD_SYNCH_FRAME                (0x0C82u)
+
+#define STD_GET_DESCRIPTOR_DEVICE                          (1u)
+#define STD_GET_DESCRIPTOR_CONFIGURATION                   (2u)
+#define STD_GET_DESCRIPTOR_STRING                          (3u)
+#define STD_GET_DESCRIPTOR_INTERFACE                       (4u)
+#define STD_GET_DESCRIPTOR_ENDPOINT                        (5u)
+#define STD_GET_DESCRIPTOR_DEVICE_QUALIFIER                (6u)
+#define STD_GET_DESCRIPTOR_OTHER_SPEED_CONFIGURATION       (7u)
+#define STD_GET_DESCRIPTOR_INTERFACE_POWER1                (8u)
+
+#define FEATURE_ENDPOINT_HALT          (0u)
+#define FEATURE_DEVICE_REMOTE_WAKEUP   (1u)
+#define FEATURE_TEST_MODE              (2u)
+
+#define STRING_INDEX_LANGUAGES         (0x00u)
+#define STRING_INDEX_MANUFACTURER      (0x01u)
+#define STRING_INDEX_PRODUCT           (0x02u)
+
+#define SAM_BA_MIN(a, b) (((a) < (b)) ? (a) : (b))
+
+
+typedef struct _USB_CDC
+{
+	// Private members
+	Usb *pUsb;
+	uint8_t currentConfiguration;
+	uint8_t currentConnection;
+	// Public Methods:
+	uint8_t (*IsConfigured)(struct _USB_CDC *pCdc);
+//	uint32_t (*Write) (Usb *pUsb, const char *pData, uint32_t length, uint8_t ep_num);
+//	uint32_t (*Read)  (Usb *pUsb, char *pData, uint32_t length);
+} USB_CDC, *P_USB_CDC;
+
+/**
+ * \brief Initializes the USB module
+ *
+ * \return Pointer to the USB CDC structure
+ */
+P_USB_CDC usb_init(void);
+
+void sam_ba_usb_CDC_Enumerate(P_USB_CDC pCdc);
+
+uint32_t USB_SendString(Usb *pUsb, const char* ascii_string, uint8_t maxLength);
+
+extern USB_CDC sam_ba_cdc;
+
+
+
+#endif // CDC_ENUMERATE_H