From 305fea327d6ffe65b6fe6c2c32a9311d06e011c3 Mon Sep 17 00:00:00 2001
From: Jake <jake.read@cba.mit.edu>
Date: Wed, 7 Feb 2018 18:58:44 -0500
Subject: [PATCH] bones of firmware / hardware wraps including spi, uart, pins

---
 circuit/mkstepper/eagle.epf                   |  24 +-
 embedded/README.md                            | 321 ++++++++++
 .../.vs/mkstepper-v011/v14/.atsuo             | Bin 0 -> 51200 bytes
 embedded/mkstepper-v011/mkstepper-v011.atsln  |  22 +
 .../mkstepper-v011/Debug/Makefile             | 182 ++++++
 .../mkstepper-v011/Debug/makedep.mk           |  18 +
 .../mkstepper-v011/Debug/mkstepper-v011.eep   |   0
 .../Device_Startup/samd51j18a_flash.ld        | 163 ++++++
 .../Device_Startup/samd51j18a_sram.ld         | 162 ++++++
 .../Device_Startup/startup_samd51.c           | 548 ++++++++++++++++++
 .../Device_Startup/system_samd51.c            |  64 ++
 .../mkstepper-v011/mkstepper-v011/hardware.h  |  30 +
 embedded/mkstepper-v011/mkstepper-v011/main.c | 161 +++++
 .../mkstepper-v011.componentinfo.xml          | 169 ++++++
 .../mkstepper-v011/mkstepper-v011.cproj       | 212 +++++++
 embedded/mkstepper-v011/mkstepper-v011/pin.c  |  42 ++
 embedded/mkstepper-v011/mkstepper-v011/pin.h  |  30 +
 .../mkstepper-v011/ringbuffer.c               |  67 +++
 .../mkstepper-v011/ringbuffer.h               |  44 ++
 .../mkstepper-v011/mkstepper-v011/spiport.c   |  95 +++
 .../mkstepper-v011/mkstepper-v011/spiport.h   |  38 ++
 .../mkstepper-v011/mkstepper-v011/uartport.c  |  97 ++++
 .../mkstepper-v011/mkstepper-v011/uartport.h  |  51 ++
 23 files changed, 2528 insertions(+), 12 deletions(-)
 create mode 100644 embedded/README.md
 create mode 100644 embedded/mkstepper-v011/.vs/mkstepper-v011/v14/.atsuo
 create mode 100644 embedded/mkstepper-v011/mkstepper-v011.atsln
 create mode 100644 embedded/mkstepper-v011/mkstepper-v011/Debug/Makefile
 create mode 100644 embedded/mkstepper-v011/mkstepper-v011/Debug/makedep.mk
 create mode 100644 embedded/mkstepper-v011/mkstepper-v011/Debug/mkstepper-v011.eep
 create mode 100644 embedded/mkstepper-v011/mkstepper-v011/Device_Startup/samd51j18a_flash.ld
 create mode 100644 embedded/mkstepper-v011/mkstepper-v011/Device_Startup/samd51j18a_sram.ld
 create mode 100644 embedded/mkstepper-v011/mkstepper-v011/Device_Startup/startup_samd51.c
 create mode 100644 embedded/mkstepper-v011/mkstepper-v011/Device_Startup/system_samd51.c
 create mode 100644 embedded/mkstepper-v011/mkstepper-v011/hardware.h
 create mode 100644 embedded/mkstepper-v011/mkstepper-v011/main.c
 create mode 100644 embedded/mkstepper-v011/mkstepper-v011/mkstepper-v011.componentinfo.xml
 create mode 100644 embedded/mkstepper-v011/mkstepper-v011/mkstepper-v011.cproj
 create mode 100644 embedded/mkstepper-v011/mkstepper-v011/pin.c
 create mode 100644 embedded/mkstepper-v011/mkstepper-v011/pin.h
 create mode 100644 embedded/mkstepper-v011/mkstepper-v011/ringbuffer.c
 create mode 100644 embedded/mkstepper-v011/mkstepper-v011/ringbuffer.h
 create mode 100644 embedded/mkstepper-v011/mkstepper-v011/spiport.c
 create mode 100644 embedded/mkstepper-v011/mkstepper-v011/spiport.h
 create mode 100644 embedded/mkstepper-v011/mkstepper-v011/uartport.c
 create mode 100644 embedded/mkstepper-v011/mkstepper-v011/uartport.h

diff --git a/circuit/mkstepper/eagle.epf b/circuit/mkstepper/eagle.epf
index 40a3930..d40b9de 100644
--- a/circuit/mkstepper/eagle.epf
+++ b/circuit/mkstepper/eagle.epf
@@ -32,12 +32,18 @@ UsedLibrary="C:/EAGLE 8.3.2/lbr/ltspice/rload.lbr"
 UsedLibrary="C:/EAGLE 8.3.2/lbr/ltspice/sym.lbr"
 
 [Win_1]
-Type="Board Editor"
+Type="Control Panel"
 Loc="0 0 1919 1016"
 State=1
+Number=0
+
+[Win_2]
+Type="Board Editor"
+Loc="0 0 1919 1016"
+State=3
 Number=2
 File="mkstepper.brd"
-View="-14.8855 10.1188 80.511 38.1294"
+View="19.1941 22.2824 34.6011 26.8063"
 WireWidths=" 0.0762 0.1016 0.127 0.4064 0.15 0.2032 0.508 1.016 0.254 0.2 2.54 0.1524 1.27 0.8128 0.6096 0.3048"
 PadDiameters=" 0.6096 0.8128 1.016 1.27 1.4224 1.6764 1.778 1.9304 2.1844 2.54 3.81 6.4516 0 0.55 0.45 0.425"
 PadDrills=" 0.2 0.25 0.4 0.45 0.5 0.55 0.65 0.7 0.75 0.8 0.85 0.9 1 0.6 0.35 0.3"
@@ -77,13 +83,13 @@ AddLevel=2
 PadsSameType=0
 Layer=16
 
-[Win_2]
+[Win_3]
 Type="Schematic Editor"
 Loc="0 0 1919 1016"
 State=1
 Number=1
 File="mkstepper.sch"
-View="-81.791 -21.5659 470.35 333.384"
+View="48.0247 158.394 176.435 240.944"
 WireWidths=" 0.0762 0.1016 0.127 0.15 0.2 0.2032 0.254 0.3048 0.4064 0.508 0.6096 0.8128 1.016 1.27 2.54 0.1524"
 PadDiameters=" 0.254 0.3048 0.4064 0.6096 0.8128 1.016 1.27 1.4224 1.6764 1.778 1.9304 2.1844 2.54 3.81 6.4516 0"
 PadDrills=" 0.2 0.25 0.3 0.35 0.4 0.45 0.5 0.55 0.65 0.7 0.75 0.8 0.85 0.9 1 0.6"
@@ -122,17 +128,11 @@ ArcDirection=0
 AddLevel=2
 PadsSameType=0
 Layer=91
-Views=" 1: -81.791 -21.5659 470.35 333.384"
+Views=" 1: 48.0247 158.394 176.435 240.944"
 Sheet="1"
 
-[Win_3]
-Type="Control Panel"
-Loc="0 0 1919 1016"
-State=1
-Number=0
-
 [Desktop]
-Screen="6000 2160"
+Screen="3840 1080"
 Window="Win_1"
 Window="Win_2"
 Window="Win_3"
diff --git a/embedded/README.md b/embedded/README.md
new file mode 100644
index 0000000..7ca92e9
--- /dev/null
+++ b/embedded/README.md
@@ -0,0 +1,321 @@
+# MK Stepper Embedded Doc
+
+My goal is to 
+ - verify that I can communicate over both UART ports to the board 
+  - now, wrap gpio and uart in tiny packages
+ - verify that I can speak SPI to the TMC2660, maybe the AS5147D.
+  - then, wrap spi into a package
+ - fiddle through tmc2660 config and send some steps
+ - send a key:value to the board that is a 'step command' - a # of steps to take over a timespan, and setup a queue of these
+
+## Ring Testing the ATSAMD51
+
+OK, first I setup the systick timer to fire every 500 cycles. This is handy - I use the interrupt to toggle a pin, then I can get a rough estimate of where the main clock is running.
+
+```C
+int main(void)
+{
+    /* Initialize the SAM system */
+    SystemInit();
+	
+	// setup blinking
+	
+	PORT->Group[1].DIRSET.reg |= (uint32_t)(1 << 13);
+	PORT->Group[1].DIRSET.reg |= (uint32_t)(1 << 14);
+	PORT->Group[1].OUTSET.reg |= (uint32_t)(1 << 13);
+	PORT->Group[1].OUTSET.reg |= (uint32_t)(1 << 14);
+	
+	// setup ring
+	
+	PORT->Group[1].DIRSET.reg |= (uint32_t)(1 << 2);
+	PORT->Group[1].OUTSET.reg |= (uint32_t)(1 << 2);
+	
+	PORT->Group[1].DIRCLR.reg = (uint32_t)(1 << 3);
+	PORT->Group[1].PINCFG[3].reg |= PORT_PINCFG_INEN;
+	PORT->Group[1].PINCFG[3].reg &= ~PORT_PINCFG_PULLEN;
+	
+	SysTick_Config(500);
+
+    while (1) 
+    {
+
+    }
+}
+
+void SysTick_Handler(void){
+	PORT->Group[1].OUTTGL.reg = (uint32_t)(1 << 2);
+	PORT->Group[1].OUTTGL.reg = (uint32_t)(1 << 14); // blink STLB
+}
+```
+
+I see 48kHz on the scope, and I know I've got a 1000x multiplier on that wave (as the scope is counting positive clock edges only, the toggle does postive-to-negative etc). So these chips set up to run at 48MHz unless we tell them otherwise. Let's try that. I'm following adafruit's bootloader code, mostly.
+
+Also, [this](https://github.com/ataradov/mcu-starter-projects/blob/master/samd21/hal_gpio.h) was nice GPIO reference for the structures used in the ATSAMD series (21 and 51). 
+
+OK, this clock is baffling me. I'm trapped at 48MHz ... going to move on for now. Somehow I want to set up the DFLL (digital frequency locked loop .. ?) to run on the 32.768kHz xtal (as a reference) with a big ol' multiplier to bring it up to 120MHz. To be honest I'm not really sure if even this is correct.
+
+In any case, here's some code for a ring test, for when I get the clock sorted. On a 48MHz clock it runs at 1.6MHz. Uses the setup above... 
+
+```C
+    while (1) 
+    {
+		//PORT->Group[1].OUTTGL.reg = (uint32_t)(1 << 2);
+		if(PORT->Group[1].IN.reg & (1 << 3)){
+			PORT->Group[1].OUTCLR.reg = (uint32_t)(1 << 2);
+		} else {
+			PORT->Group[1].OUTSET.reg = (uint32_t)(1 << 2);
+		}
+    }
+```
+
+## USART on the ATSAMD51
+
+Altogether more registers than I'd like to manage, but here we are.
+
+```C
+
+int main(void)
+{
+    /* Initialize the SAM system */
+    SystemInit();
+	
+	//clock_init();
+	
+	/*setup blinking
+	STLR		PB13
+	STLB		PB14
+	*/
+	PORT->Group[1].DIRSET.reg |= (uint32_t)(1 << 13);
+	PORT->Group[1].DIRSET.reg |= (uint32_t)(1 << 14);
+	PORT->Group[1].OUTSET.reg |= (uint32_t)(1 << 13);
+	PORT->Group[1].OUTSET.reg |= (uint32_t)(1 << 14);
+	
+	SysTick_Config(5000000);
+	
+	/* setup UARTs
+	NP1RX		PA12 / SER4-1
+	NP1TX		PA13 / SER4-0
+
+	NP2RX		PB03 / SER5-1 / Peripheral D
+	NP2TX		PB02 / SER5-0 / Peripheral D
+	*/
+	
+	// setup pins for peripheral
+	PORT->Group[1].DIRCLR.reg = (uint32_t)(1 << 3); // rx is input
+	PORT->Group[1].DIRSET.reg = (uint32_t)(1 << 2); // tx output
+	PORT->Group[1].PINCFG[3].bit.PMUXEN = 1;
+	PORT->Group[1].PMUX[3>>1].reg |= PORT_PMUX_PMUXE(0x3); 
+	PORT->Group[1].PMUX[3>>3].reg |= PORT_PMUX_PMUXO(0x3);
+	PORT->Group[1].PINCFG[2].bit.PMUXEN = 1;
+	PORT->Group[1].PMUX[2>>1].reg |= PORT_PMUX_PMUXE(0x3);
+	PORT->Group[1].PMUX[2>>3].reg |= PORT_PMUX_PMUXO(0x3);
+	// unmask clocks
+	MCLK->APBDMASK.reg |= MCLK_APBDMASK_SERCOM5;
+	// generate clocks to, starting with clock 6 (arbitrary choice, lower # held for system things)
+	// datasheet says normally one gclk per peripheral shrugman knows why
+	GCLK->GENCTRL[6].reg = GCLK_GENCTRL_SRC(GCLK_GENCTRL_SRC_DFLL) | GCLK_GENCTRL_GENEN;
+	while(GCLK->SYNCBUSY.reg & GCLK_SYNCBUSY_GENCTRL6);
+	GCLK->PCHCTRL[SERCOM5_GCLK_ID_CORE].reg = GCLK_PCHCTRL_CHEN | GCLK_PCHCTRL_GEN_GCLK6;
+	// now the sercom
+	while(SERCOM5->USART.SYNCBUSY.bit.ENABLE);
+	SERCOM5->USART.CTRLA.bit.ENABLE = 0;
+	while(SERCOM5->USART.SYNCBUSY.bit.SWRST);
+	SERCOM5->USART.CTRLA.bit.SWRST = 1;
+	while(SERCOM5->USART.SYNCBUSY.bit.SWRST);
+	while(SERCOM5->USART.SYNCBUSY.bit.SWRST || SERCOM5->USART.SYNCBUSY.bit.ENABLE);
+	// now reset and ready, do config
+	SERCOM5->USART.CTRLA.reg = SERCOM_USART_CTRLA_MODE(1) | SERCOM_USART_CTRLA_DORD | SERCOM_USART_CTRLA_RXPO(1) | SERCOM_USART_CTRLA_TXPO(0);
+	while(SERCOM5->USART.SYNCBUSY.bit.CTRLB);
+	SERCOM5->USART.CTRLB.reg = SERCOM_USART_CTRLB_RXEN | SERCOM_USART_CTRLB_TXEN | SERCOM_USART_CTRLB_CHSIZE(0);
+	/*
+	BAUD = 65536*(1-S*(fBAUD/fref))
+	where S is samples per bit, 16 for async uart
+	where fBAUD is the rate that you want
+	where fref is the peripheral clock from GCLK, in this case (and most) 48MHz
+	*/
+	SERCOM5->USART.BAUD.reg = 45402;
+	while(SERCOM5->USART.SYNCBUSY.bit.ENABLE);
+	SERCOM5->USART.CTRLA.bit.ENABLE = 1;
+	
+	
+    while (1) 
+    {
+		while(!SERCOM5->USART.INTFLAG.bit.DRE);
+		SERCOM5->USART.DATA.reg = (uint8_t)170;
+    }
+}
+
+void SysTick_Handler(void){
+	PORT->Group[1].OUTTGL.reg = (uint32_t)(1 << 14); // blink STLB
+}
+```
+
+## Interrupts on the ATSAMD51
+
+To configure an interrupt on the ATSAMD51, roughly, we do this:
+
+```C
+
+int main(void){
+
+	__enable_irq(); // globally enables the NVIC
+
+	// turns on a particular 'irq line' or 'irq number'
+	// for example, in the SERCOM->UART section of the datasheet, 
+	// see 34.8.8 - the interrupt 'flag' sections. these are analagous to 'line numbers'
+	// and are linked to 'interrupt numbers' per 10.2.2
+	NVIC_EnableIRQ(SERCOM4_2_IRQn); 
+}
+
+// we can then handle the interrupt:
+
+void SERCOM4_2_Handler(void){
+	// we must clear the flag, often this is done by reading the flag register, like this:
+	// SERCOM4->USART->INTFLAG.bit.RXC = 1; // odd, writing '1' is normally the way to clear it
+	// however, for this particular register, we read the data from the peripheral to clear the interrupt.
+	uint8_t data = SERCOM4->USART.DATA.reg;
+	pin_clear(&stlr); // indicate
+	// then we would presumably do something
+}
+
+```
+
+TODO: make ATSAMD51 doc page for all of this bringup !
+
+## Async-happy USART
+
+To handle USART on these systems, I implement a (hopefully) bulletproof and interrupt-friendly architecture.
+
+TX and RX both have interrupt handlers - the RX dumps bytes into a ringbuffer for the application to poll later on (polling the ringbuffer, not the UART hardware) and the TX buffer is set up so that the application can dump a block of bytes into the transmitter at once, without waiting for anything to transmit. 
+
+```C
+
+int main(void)
+{
+    /* Initialize the SAM system */
+    SystemInit();
+	SysTick_Config(5000000);
+	
+	//clock_init();
+	
+	// lights
+	
+	stlb = pin_new(&PORT->Group[1], 14);
+	pin_output(&stlb);
+	pin_set(&stlb);
+	stlr = pin_new(&PORT->Group[1], 13);
+	pin_output(&stlr);
+	pin_set(&stlr);
+	
+	// ready interrupt system
+	__enable_irq();
+	NVIC_EnableIRQ(SERCOM4_0_IRQn); //up1tx
+	NVIC_EnableIRQ(SERCOM4_2_IRQn); //up1rx
+	NVIC_EnableIRQ(SERCOM5_0_IRQn);
+	NVIC_EnableIRQ(SERCOM5_2_IRQn);
+	
+	// ringbuffers (for uart ports)
+	rb_init(&up1_rbrx);
+	rb_init(&up1_rbtx);
+	rb_init(&up2_rbrx);
+	rb_init(&up2_rbtx);
+	
+	// uarts (ports)
+	// TODO: have used PMUXO and PMUXE incorrectly: only set one of these, based on whether / not pin is even / odd !
+	
+	up1 = uart_new(SERCOM4, &PORT->Group[0], &up1_rbrx, &up1_rbtx, 12, 13, HARDWARE_IS_APBD, HARDWARE_ON_PERIPHERAL_D); 
+	MCLK->APBDMASK.reg |= MCLK_APBDMASK_SERCOM4;
+	uart_init(&up1, 6, SERCOM4_GCLK_ID_CORE, 63018); // baud: 45402 for 921600, 63018 for 115200
+	up2 = uart_new(SERCOM5, &PORT->Group[1], &up2_rbrx, &up2_rbtx, 3, 2, HARDWARE_IS_APBD, HARDWARE_ON_PERIPHERAL_D);
+	MCLK->APBDMASK.reg |= MCLK_APBDMASK_SERCOM5;
+	uart_init(&up2, 7, SERCOM5_GCLK_ID_CORE, 63018);
+	
+	
+	// SPI
+	// TMC_MOSI		PA07 / SER0-3
+	// TMC_MISO		PA04 / SER0-0
+	// TMC_SCK		PA05 / SER0-1
+	// TMC_CSN		PA06 / SER0-2
+	
+	// spi
+	spi_tmc = spi_new(SERCOM0, &PORT->Group[0], 4, 7, 5, 6, HARDWARE_IS_APBA, HARDWARE_ON_PERIPHERAL_D);
+	MCLK->APBAMASK.reg |= MCLK_APBAMASK_SERCOM0;
+	spi_init(&spi_tmc, 8, SERCOM0_GCLK_ID_CORE, 126, 0, 2);
+	
+	// -> DO SPI, talk to the TMC !
+		
+    while (1) 
+    {
+		// spi_txchar_polled(&spitmc, 'x');
+		// find TMC registers now, try to read!
+		
+    }
+}
+
+void SysTick_Handler(void){
+	pin_toggle(&stlb);
+	while(!rb_empty(up1.rbrx)){
+		uart_sendchar_buffered(&up1, rb_get(up1.rbrx));
+	}
+}
+
+void SERCOM4_0_Handler(void){
+	uart_txhandler(&up1);
+}
+
+void SERCOM4_2_Handler(void){
+	uart_rxhandler(&up1);
+}
+
+void SERCOM5_0_Handler(void){
+	uart_txhandler(&up2);
+}
+
+void SERCOM5_2_Handler(void){
+	uart_rxhandler(&up2);
+}
+```
+
+and 
+
+```C
+
+void uart_sendchar_polled(uartport_t *uart, uint8_t data){
+	while(!uart->com->USART.INTFLAG.bit.DRE);
+	uart->com->USART.DATA.reg = data;
+}
+
+void uart_sendchar_buffered(uartport_t *uart, uint8_t data){
+	rb_putchar(uart->rbtx, data); // dump it in there
+	uart->com->USART.INTENSET.bit.DRE = 1; // set up the volley
+}
+
+void uart_rxhandler(uartport_t *uart){
+	uint8_t data = uart->com->USART.DATA.reg;
+	rb_putchar(uart->rbrx, data);
+}
+
+void uart_txhandler(uartport_t *uart){
+	if(!rb_empty(uart->rbtx)){
+		uart->com->USART.DATA.reg = rb_get(uart->rbtx);
+	} else {
+		uart->com->USART.INTENCLR.reg = SERCOM_USART_INTENCLR_DRE;
+	}
+}
+```
+
+## Trinamic Bit-Fiddling
+
+Next I'm going to try to get some steps to happen. I guess we're ready for this!
+
+I found [this](https://github.com/trinamic/TMC26XStepper) library. 
+
+# the end of this day
+
+- dinner
+- tell anna you can't handle meeting b/c NSF
+- setup to be doing NSF only tomorrow
+- get whatever you can get done today
+- maybe kill / handle: dome ... anything else you feel is 'loose'
+ - lots of emails
+ - cleaning up
\ No newline at end of file
diff --git a/embedded/mkstepper-v011/.vs/mkstepper-v011/v14/.atsuo b/embedded/mkstepper-v011/.vs/mkstepper-v011/v14/.atsuo
new file mode 100644
index 0000000000000000000000000000000000000000..b14b68e3dd1cd02342db41b3d6c09b1e92b2ab3d
GIT binary patch
literal 51200
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

literal 0
HcmV?d00001

diff --git a/embedded/mkstepper-v011/mkstepper-v011.atsln b/embedded/mkstepper-v011/mkstepper-v011.atsln
new file mode 100644
index 0000000..0b9dfe8
--- /dev/null
+++ b/embedded/mkstepper-v011/mkstepper-v011.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}") = "mkstepper-v011", "mkstepper-v011\mkstepper-v011.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/mkstepper-v011/mkstepper-v011/Debug/Makefile b/embedded/mkstepper-v011/mkstepper-v011/Debug/Makefile
new file mode 100644
index 0000000..7d21dd2
--- /dev/null
+++ b/embedded/mkstepper-v011/mkstepper-v011/Debug/Makefile
@@ -0,0 +1,182 @@
+################################################################################
+# 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 +=  \
+../Device_Startup/startup_samd51.c \
+../Device_Startup/system_samd51.c \
+../main.c \
+../pin.c \
+../ringbuffer.c \
+../spiport.c \
+../uartport.c
+
+
+PREPROCESSING_SRCS += 
+
+
+ASM_SRCS += 
+
+
+OBJS +=  \
+Device_Startup/startup_samd51.o \
+Device_Startup/system_samd51.o \
+main.o \
+pin.o \
+ringbuffer.o \
+spiport.o \
+uartport.o
+
+OBJS_AS_ARGS +=  \
+Device_Startup/startup_samd51.o \
+Device_Startup/system_samd51.o \
+main.o \
+pin.o \
+ringbuffer.o \
+spiport.o \
+uartport.o
+
+C_DEPS +=  \
+Device_Startup/startup_samd51.d \
+Device_Startup/system_samd51.d \
+main.d \
+pin.d \
+ringbuffer.d \
+spiport.d \
+uartport.d
+
+C_DEPS_AS_ARGS +=  \
+Device_Startup/startup_samd51.d \
+Device_Startup/system_samd51.d \
+main.d \
+pin.d \
+ringbuffer.d \
+spiport.d \
+uartport.d
+
+OUTPUT_FILE_PATH +=mkstepper-v011.elf
+
+OUTPUT_FILE_PATH_AS_ARGS +=mkstepper-v011.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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+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: $<
+	
+
+./%.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: $<
+	
+
+
+
+# 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="mkstepper-v011.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 "mkstepper-v011.elf" "mkstepper-v011.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  "mkstepper-v011.elf" "mkstepper-v011.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 "mkstepper-v011.elf" "mkstepper-v011.eep" || exit 0
+	"C:\Program Files (x86)\Atmel\Studio\7.0\toolchain\arm\arm-gnu-toolchain\bin\arm-none-eabi-objdump.exe" -h -S "mkstepper-v011.elf" > "mkstepper-v011.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  "mkstepper-v011.elf" "mkstepper-v011.srec"
+	"C:\Program Files (x86)\Atmel\Studio\7.0\toolchain\arm\arm-gnu-toolchain\bin\arm-none-eabi-size.exe" "mkstepper-v011.elf"
+	
+	
+
+
+
+
+
+# Other Targets
+clean:
+	-$(RM) $(OBJS_AS_ARGS) $(EXECUTABLES)  
+	-$(RM) $(C_DEPS_AS_ARGS)   
+	rm -rf "mkstepper-v011.elf" "mkstepper-v011.a" "mkstepper-v011.hex" "mkstepper-v011.bin" "mkstepper-v011.lss" "mkstepper-v011.eep" "mkstepper-v011.map" "mkstepper-v011.srec"
+	
\ No newline at end of file
diff --git a/embedded/mkstepper-v011/mkstepper-v011/Debug/makedep.mk b/embedded/mkstepper-v011/mkstepper-v011/Debug/makedep.mk
new file mode 100644
index 0000000..bd15a24
--- /dev/null
+++ b/embedded/mkstepper-v011/mkstepper-v011/Debug/makedep.mk
@@ -0,0 +1,18 @@
+################################################################################
+# Automatically-generated file. Do not edit or delete the file
+################################################################################
+
+Device_Startup\startup_samd51.c
+
+Device_Startup\system_samd51.c
+
+main.c
+
+pin.c
+
+ringbuffer.c
+
+spiport.c
+
+uartport.c
+
diff --git a/embedded/mkstepper-v011/mkstepper-v011/Debug/mkstepper-v011.eep b/embedded/mkstepper-v011/mkstepper-v011/Debug/mkstepper-v011.eep
new file mode 100644
index 0000000..e69de29
diff --git a/embedded/mkstepper-v011/mkstepper-v011/Device_Startup/samd51j18a_flash.ld b/embedded/mkstepper-v011/mkstepper-v011/Device_Startup/samd51j18a_flash.ld
new file mode 100644
index 0000000..301f100
--- /dev/null
+++ b/embedded/mkstepper-v011/mkstepper-v011/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/mkstepper-v011/mkstepper-v011/Device_Startup/samd51j18a_sram.ld b/embedded/mkstepper-v011/mkstepper-v011/Device_Startup/samd51j18a_sram.ld
new file mode 100644
index 0000000..0303f06
--- /dev/null
+++ b/embedded/mkstepper-v011/mkstepper-v011/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/mkstepper-v011/mkstepper-v011/Device_Startup/startup_samd51.c b/embedded/mkstepper-v011/mkstepper-v011/Device_Startup/startup_samd51.c
new file mode 100644
index 0000000..a62d02f
--- /dev/null
+++ b/embedded/mkstepper-v011/mkstepper-v011/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/mkstepper-v011/mkstepper-v011/Device_Startup/system_samd51.c b/embedded/mkstepper-v011/mkstepper-v011/Device_Startup/system_samd51.c
new file mode 100644
index 0000000..2df9920
--- /dev/null
+++ b/embedded/mkstepper-v011/mkstepper-v011/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/mkstepper-v011/mkstepper-v011/hardware.h b/embedded/mkstepper-v011/mkstepper-v011/hardware.h
new file mode 100644
index 0000000..ad2481e
--- /dev/null
+++ b/embedded/mkstepper-v011/mkstepper-v011/hardware.h
@@ -0,0 +1,30 @@
+/*
+ * hardware.h
+ *
+ * Created: 2/5/2018 11:50:30 PM
+ *  Author: Jake
+ */ 
+
+
+#ifndef HARDWARE_H_
+#define HARDWARE_H_
+
+#include "pin.h"
+#include "uartport.h"
+#include "spiport.h"
+#include "ringbuffer.h"
+
+pin_t stlr;
+pin_t stlb;
+
+ringbuffer_t up1_rbrx;
+ringbuffer_t up1_rbtx;
+ringbuffer_t up2_rbrx;
+ringbuffer_t up2_rbtx;
+
+uartport_t up1;
+uartport_t up2;
+
+spiport_t spi_tmc;
+
+#endif /* HARDWARE_H_ */
\ No newline at end of file
diff --git a/embedded/mkstepper-v011/mkstepper-v011/main.c b/embedded/mkstepper-v011/mkstepper-v011/main.c
new file mode 100644
index 0000000..c68636a
--- /dev/null
+++ b/embedded/mkstepper-v011/mkstepper-v011/main.c
@@ -0,0 +1,161 @@
+/*
+ * mkstepper-v011.c
+ *
+ * Created: 2/5/2018 12:00:35 PM
+ * Author : Jake
+ */ 
+
+
+#include "sam.h"
+#include "pin.h"
+#include "uartport.h"
+#include "spiport.h"
+
+#include "hardware.h"
+
+/* PINS 
+
+STLR		PB13
+STLB		PB14
+
+NP1RX		PA12 / SER4-1
+NP1TX		PA13 / SER4-0
+
+NP2RX		PB03 / SER5-1
+NP2TX		PB02 / SER5-0
+
+TMC_SG		PB08
+TMC_EN		PB07
+STEP		PB08
+DIR			PB09
+
+TMC_MOSI	PA07 / SER0-3
+TMC_MISO	PA04 / SER0-0
+TMC_SCK		PA05 / SER0-1
+TMC_CSN		PA06 / SER0-2
+
+AS_MOSI		PA11 / SER2-3
+AS_MISO		PA08 / SER2-1
+AS_SCK		PA09 / SER2-0
+AS_CSN		PA10 / SER2-2
+
+*/
+
+void clock_init(void){
+	
+	// on Reset, the DFLL48< source clock is on and running at 48MHz
+	// GCLK0 uses DFLL48M as a source and generates GCLK_MAIN
+	// we want to use OSCCTRL to (1) set the DFLL48M to run on a reference clock, in closed-loop mode
+	// (20 then to prescale the DFLL48M such that it runs at 120MHz
+	
+	// generic clock channel 0 is the reference for the DFLL - we'll try to set that up first
+		
+	OSCCTRL->DFLLMUL.reg = OSCCTRL_DFLLMUL_MUL(20) | OSCCTRL_DFLLMUL_CSTEP(12) | OSCCTRL_DFLLMUL_FSTEP(5);
+	while(OSCCTRL->DFLLSYNC.reg & OSCCTRL_DFLLSYNC_DFLLMUL){
+		// wait
+	}
+	
+	OSCCTRL->DFLLCTRLA.reg = OSCCTRL_DFLLCTRLA_ENABLE | OSCCTRL_DFLLCTRLA_RUNSTDBY;
+	while(OSCCTRL->DFLLSYNC.reg & OSCCTRL_DFLLSYNC_ENABLE){
+		// wait
+	}
+	
+	OSCCTRL->DFLLVAL.reg = OSCCTRL_DFLLVAL_COARSE(12) | OSCCTRL_DFLLVAL_FINE(12);
+	while(OSCCTRL->DFLLSYNC.reg & OSCCTRL_DFLLSYNC_DFLLVAL){
+		// wait
+	}
+	
+	OSCCTRL->DFLLCTRLB.reg = OSCCTRL_DFLLCTRLB_MODE | OSCCTRL_DFLLCTRLB_WAITLOCK;
+	while(OSCCTRL->DFLLSYNC.reg & OSCCTRL_DFLLSYNC_DFLLCTRLB){
+		// wait
+	}
+	
+	while(!OSCCTRL->STATUS.bit.DFLLRDY);
+	
+	MCLK->CPUDIV.reg = MCLK_CPUDIV_DIV_DIV1;
+}
+
+int main(void)
+{
+    /* Initialize the SAM system */
+    SystemInit();
+	SysTick_Config(5000000);
+	
+	//clock_init();
+	
+	// lights
+	
+	stlb = pin_new(&PORT->Group[1], 14);
+	pin_output(&stlb);
+	pin_set(&stlb);
+	stlr = pin_new(&PORT->Group[1], 13);
+	pin_output(&stlr);
+	pin_set(&stlr);
+	
+	// ready interrupt system
+	__enable_irq();
+	NVIC_EnableIRQ(SERCOM4_0_IRQn); //up1tx
+	NVIC_EnableIRQ(SERCOM4_2_IRQn); //up1rx
+	NVIC_EnableIRQ(SERCOM5_0_IRQn);
+	NVIC_EnableIRQ(SERCOM5_2_IRQn);
+	
+	// ringbuffers (for uart ports)
+	rb_init(&up1_rbrx);
+	rb_init(&up1_rbtx);
+	rb_init(&up2_rbrx);
+	rb_init(&up2_rbtx);
+	
+	// uarts (ports)
+	// TODO: have used PMUXO and PMUXE incorrectly: only set one of these, based on whether / not pin is even / odd !
+	
+	up1 = uart_new(SERCOM4, &PORT->Group[0], &up1_rbrx, &up1_rbtx, 12, 13, HARDWARE_IS_APBD, HARDWARE_ON_PERIPHERAL_D); 
+	MCLK->APBDMASK.reg |= MCLK_APBDMASK_SERCOM4;
+	uart_init(&up1, 6, SERCOM4_GCLK_ID_CORE, 63018); // baud: 45402 for 921600, 63018 for 115200
+	up2 = uart_new(SERCOM5, &PORT->Group[1], &up2_rbrx, &up2_rbtx, 3, 2, HARDWARE_IS_APBD, HARDWARE_ON_PERIPHERAL_D);
+	MCLK->APBDMASK.reg |= MCLK_APBDMASK_SERCOM5;
+	uart_init(&up2, 7, SERCOM5_GCLK_ID_CORE, 63018);
+	
+	
+	// SPI
+	// TMC_MOSI		PA07 / SER0-3
+	// TMC_MISO		PA04 / SER0-0
+	// TMC_SCK		PA05 / SER0-1
+	// TMC_CSN		PA06 / SER0-2
+	
+	// spi
+	spi_tmc = spi_new(SERCOM0, &PORT->Group[0], 4, 7, 5, 6, HARDWARE_IS_APBA, HARDWARE_ON_PERIPHERAL_D);
+	MCLK->APBAMASK.reg |= MCLK_APBAMASK_SERCOM0;
+	spi_init(&spi_tmc, 8, SERCOM0_GCLK_ID_CORE, 126, 0, 2);
+	
+	// -> DO SPI, talk to the TMC !
+		
+    while (1) 
+    {
+		// spi_txchar_polled(&spitmc, 'x');
+		// find TMC registers now, try to read!
+		
+    }
+}
+
+void SysTick_Handler(void){
+	pin_toggle(&stlb);
+	while(!rb_empty(up1.rbrx)){
+		uart_sendchar_buffered(&up1, rb_get(up1.rbrx));
+	}
+}
+
+void SERCOM4_0_Handler(void){
+	uart_txhandler(&up1);
+}
+
+void SERCOM4_2_Handler(void){
+	uart_rxhandler(&up1);
+}
+
+void SERCOM5_0_Handler(void){
+	uart_txhandler(&up2);
+}
+
+void SERCOM5_2_Handler(void){
+	uart_rxhandler(&up2);
+}
\ No newline at end of file
diff --git a/embedded/mkstepper-v011/mkstepper-v011/mkstepper-v011.componentinfo.xml b/embedded/mkstepper-v011/mkstepper-v011/mkstepper-v011.componentinfo.xml
new file mode 100644
index 0000000..4c98a95
--- /dev/null
+++ b/embedded/mkstepper-v011/mkstepper-v011/mkstepper-v011.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>AkDwjED0tMpIjyJPo6itfg==</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/mkstepper-v011/mkstepper-v011/mkstepper-v011.cproj b/embedded/mkstepper-v011/mkstepper-v011/mkstepper-v011.cproj
new file mode 100644
index 0000000..0f4e9d1
--- /dev/null
+++ b/embedded/mkstepper-v011/mkstepper-v011/mkstepper-v011.cproj
@@ -0,0 +1,212 @@
+<?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>mkstepper-v011</AssemblyName>
+    <Name>mkstepper-v011</Name>
+    <RootNamespace>mkstepper-v011</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.36.2" />
+        </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.memorysettings.ExternalRAM />
+  <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="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="ringbuffer.c">
+      <SubType>compile</SubType>
+    </Compile>
+    <Compile Include="ringbuffer.h">
+      <SubType>compile</SubType>
+    </Compile>
+    <Compile Include="spiport.c">
+      <SubType>compile</SubType>
+    </Compile>
+    <Compile Include="spiport.h">
+      <SubType>compile</SubType>
+    </Compile>
+    <Compile Include="uartport.c">
+      <SubType>compile</SubType>
+    </Compile>
+    <Compile Include="uartport.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/mkstepper-v011/mkstepper-v011/pin.c b/embedded/mkstepper-v011/mkstepper-v011/pin.c
new file mode 100644
index 0000000..6bf2a5e
--- /dev/null
+++ b/embedded/mkstepper-v011/mkstepper-v011/pin.c
@@ -0,0 +1,42 @@
+/*
+ * pin.c
+ *
+ * Created: 2/5/2018 11:21:37 PM
+ *  Author: Jake
+ */ 
+
+#include "pin.h"
+#include "sam.h"
+
+pin_t pin_new(PortGroup *port, uint32_t pin_number){
+	pin_t pin;
+	pin.port = port;
+	pin.bm = (uint32_t)(1 << 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;
+}
+
+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;
+}
\ No newline at end of file
diff --git a/embedded/mkstepper-v011/mkstepper-v011/pin.h b/embedded/mkstepper-v011/mkstepper-v011/pin.h
new file mode 100644
index 0000000..8ea143d
--- /dev/null
+++ b/embedded/mkstepper-v011/mkstepper-v011/pin.h
@@ -0,0 +1,30 @@
+/*
+ * 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
+} pin_t;
+
+pin_t pin_new(PortGroup *port, uint32_t pin);
+
+void pin_output(pin_t *pin);
+void pin_input(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_ */
\ No newline at end of file
diff --git a/embedded/mkstepper-v011/mkstepper-v011/ringbuffer.c b/embedded/mkstepper-v011/mkstepper-v011/ringbuffer.c
new file mode 100644
index 0000000..c7743e4
--- /dev/null
+++ b/embedded/mkstepper-v011/mkstepper-v011/ringbuffer.c
@@ -0,0 +1,67 @@
+/*
+ * ringbuffer.c
+ *
+ * Created: 2/7/2018 11:39:44 AM
+ *  Author: Jake
+ */ 
+
+#include "ringbuffer.h"
+
+uint8_t rb_init(ringbuffer_t *rb){
+	rb->size = RINGBUFFER_SIZE; // stuck with this, due to not having malloc, wall of skill
+	//rb->buffer = malloc(size);
+	rb_reset(rb);
+	return 1;
+}
+
+uint8_t rb_reset(ringbuffer_t *rb){
+	if(rb){
+		rb->head = 0;
+		rb->tail = 0;
+		return 1;
+	} else {
+		return 0;
+	}
+}
+
+uint8_t rb_empty(ringbuffer_t *rb){
+	return (rb->head == rb->tail);
+}
+
+uint8_t rb_full(ringbuffer_t *rb){
+	return ((rb->head + 1) % rb->size) == rb->tail;
+}
+
+uint8_t rb_freespace(ringbuffer_t *rb){
+	if(rb->head >= rb->tail){
+		return rb->size - (rb->head - rb->tail);
+	} else {
+		return rb->tail - rb->head - 1;
+	}
+}
+
+uint8_t rb_putchar(ringbuffer_t *rb, uint8_t data){
+	rb->buffer[rb->head] = data;
+	rb->head = (rb->head + 1) % rb->size; // increment and loop about
+	return 1;
+}
+
+uint8_t rb_putdata(ringbuffer_t *rb, uint8_t *data, uint8_t size){
+	if(rb_freespace(rb) <= size){
+		return 0;
+	} else {
+		uint8_t i = 0;
+		while(i < size){
+			rb_putchar(rb, data[i]);
+			i ++;
+		}
+		return 1;
+	}
+}
+
+uint8_t rb_get(ringbuffer_t *rb){
+	uint8_t data = rb->buffer[rb->tail];
+	rb->tail = (rb->tail + 1) % rb->size;
+	return data;
+}
+
diff --git a/embedded/mkstepper-v011/mkstepper-v011/ringbuffer.h b/embedded/mkstepper-v011/mkstepper-v011/ringbuffer.h
new file mode 100644
index 0000000..889caf9
--- /dev/null
+++ b/embedded/mkstepper-v011/mkstepper-v011/ringbuffer.h
@@ -0,0 +1,44 @@
+/*
+ * ringbuffer.h
+ *
+ * Created: 2/7/2018 11:39:54 AM
+ *  Author: Jake
+ */ 
+
+#ifndef RINGBUFFER_H_
+#define RINGBUFFER_H_
+
+/*
+a ringbuffer,
+s/o https://github.com/dhess/c-ringbuf
+s/o https://embeddedartistry.com/blog/2017/4/6/circular-buffers-in-cc
+s/o https://www.downtowndougbrown.com/2013/01/microcontrollers-interrupt-safe-ring-buffers/
+*/
+
+#include "sam.h"
+
+#include <stdlib.h> // for size_t
+
+#define RINGBUFFER_SIZE 256
+
+typedef struct{
+	uint8_t buffer[256]; // static! big enough
+	size_t head;
+	size_t tail;
+	size_t size;
+} ringbuffer_t;
+
+uint8_t rb_init(ringbuffer_t *rb);
+
+uint8_t rb_reset(ringbuffer_t *rb);
+
+uint8_t rb_empty(ringbuffer_t *rb);
+uint8_t rb_full(ringbuffer_t *rb);
+uint8_t rb_freespace(ringbuffer_t *rb);
+
+uint8_t rb_putchar(ringbuffer_t *rb, uint8_t data);
+uint8_t rb_putdata(ringbuffer_t *rb, uint8_t *data, uint8_t size);
+
+uint8_t rb_get(ringbuffer_t *rb);
+
+#endif /* RINGBUFFER_H_ */
\ No newline at end of file
diff --git a/embedded/mkstepper-v011/mkstepper-v011/spiport.c b/embedded/mkstepper-v011/mkstepper-v011/spiport.c
new file mode 100644
index 0000000..8fe8b56
--- /dev/null
+++ b/embedded/mkstepper-v011/mkstepper-v011/spiport.c
@@ -0,0 +1,95 @@
+/*
+ * spiport.c
+ *
+ * Created: 2/7/2018 10:51:42 AM
+ *  Author: Jake
+ */ 
+
+#include "spiport.h"
+
+spiport_t spi_new(Sercom *com, PortGroup *port, uint32_t miso_pin, uint32_t mosi_pin, uint32_t sck_pin, uint32_t csn_pin, uint32_t apbx, uint32_t peripheral){
+	spiport_t spi;
+	
+	spi.com = com;
+	spi.port = port;
+	
+	spi.miso_pin = miso_pin;
+	spi.miso_bm = (uint32_t)(1 << miso_pin);
+	spi.mosi_pin = mosi_pin;
+	spi.mosi_bm = (uint32_t)(1 << mosi_pin);
+	spi.sck_pin = sck_pin;
+	spi.sck_bm = (uint32_t)(1 << sck_pin);
+	spi.csn_pin = csn_pin;
+	spi.csn_bm = (uint32_t)(1 << csn_pin);
+	
+	spi.apbx = apbx;
+	spi.peripheral = peripheral;
+	
+	return spi;
+}
+
+void spi_init(spiport_t *spi, uint32_t gclknum, uint32_t gclkidcore, uint8_t baud, uint32_t dipo, uint32_t dopo){
+	// clk is unmasked (external to this lib)
+	// do pin configs
+	spi->port->DIRCLR.reg |= spi->miso_bm;
+	spi->port->PINCFG[spi->miso_pin].bit.PMUXEN = 1;
+	spi->port->DIRSET.reg |= spi->mosi_bm | spi->sck_bm | spi->csn_bm;
+	spi->port->PINCFG[spi->mosi_pin].bit.PMUXEN = 1;
+	spi->port->PINCFG[spi->sck_pin].bit.PMUXEN = 1;
+	spi->port->PINCFG[spi->csn_pin].bit.PMUXEN = 1;
+	
+	if(spi->miso_pin % 2){ // yes if odd
+		spi->port->PMUX[spi->miso_pin >> 1].reg |= PORT_PMUX_PMUXO(spi->peripheral);
+	} else {
+		spi->port->PMUX[spi->miso_pin >> 1].reg |= PORT_PMUX_PMUXE(spi->peripheral);
+	}
+	
+	if(spi->mosi_pin % 2){ // yes if odd
+		spi->port->PMUX[spi->mosi_pin >> 1].reg |= PORT_PMUX_PMUXO(spi->peripheral);
+		} else {
+		spi->port->PMUX[spi->mosi_pin >> 1].reg |= PORT_PMUX_PMUXE(spi->peripheral);
+	}
+	
+	if(spi->sck_pin % 2){ // yes if odd
+		spi->port->PMUX[spi->sck_pin >> 1].reg |= PORT_PMUX_PMUXO(spi->peripheral);
+		} else {
+		spi->port->PMUX[spi->sck_pin >> 1].reg |= PORT_PMUX_PMUXE(spi->peripheral);
+	}
+	
+	if(spi->csn_pin % 2){ // yes if odd
+		spi->port->PMUX[spi->csn_pin >> 1].reg |= PORT_PMUX_PMUXO(spi->peripheral);
+		} else {
+		spi->port->PMUX[spi->csn_pin >> 1].reg |= PORT_PMUX_PMUXE(spi->peripheral);
+	}
+	
+	// build a clock for
+	GCLK->GENCTRL[gclknum].reg = GCLK_GENCTRL_SRC(GCLK_GENCTRL_SRC_DFLL) | GCLK_GENCTRL_GENEN;
+	while(GCLK->SYNCBUSY.reg & GCLK_SYNCBUSY_GENCTRL(gclknum));
+	GCLK->PCHCTRL[gclkidcore].reg = GCLK_PCHCTRL_CHEN | GCLK_PCHCTRL_GEN(gclknum);
+	
+	// now some SERCOM
+	spi->com->SPI.CTRLA.bit.ENABLE = 0;
+	// master, data in pinout, data out pinout
+	spi->com->SPI.CTRLA.reg |= SERCOM_SPI_CTRLA_MODE(0x03);
+	//SERCOM0->SPI.CTRLA.reg |= SERCOM_SPI_CTRLA_CPHA | SERCOM_SPI_CTRLA_CPOL;
+	spi->com->SPI.CTRLA.reg |= SERCOM_SPI_CTRLA_DIPO(dipo) | SERCOM_SPI_CTRLA_DOPO(dopo);
+	// these to defaults, but here for show
+	//SERCOM0->SPI.CTRLA.reg |= SERCOM_SPI_CTRLA_DORD; // 0 MSB, 1 LSB
+	//SERCOM0->SPI.CTRLB.reg |= SERCOM_SPI_CTRLB_CHSIZE(0x0); // 8 bits character - 0x0, so no need to set
+	// BAUD
+	// f_baud = f_ref / (2 * (BAUD +1)) so BAUD = f_ref / (2 * f_baud) - 1
+	spi->com->SPI.BAUD.reg |= SERCOM_SPI_BAUD_BAUD(baud);
+	// use hardware slave select, enable receiver
+	spi->com->SPI.CTRLB.reg |= SERCOM_SPI_CTRLB_MSSEN | SERCOM_SPI_CTRLB_RXEN;
+	// turnt it up
+	spi->com->SPI.CTRLA.bit.ENABLE = 1;
+}
+
+void spi_txchar_polled(spiport_t *spi, uint8_t data){
+	while(!(spi->com->SPI.INTFLAG.bit.DRE));
+	spi->com->SPI.DATA.reg = SERCOM_SPI_DATA_DATA(data);
+}
+
+void spi_txrxchar_polled(spiport_t *spi, uint8_t data, uint8_t *rxdata){
+	// how to read?
+}
\ No newline at end of file
diff --git a/embedded/mkstepper-v011/mkstepper-v011/spiport.h b/embedded/mkstepper-v011/mkstepper-v011/spiport.h
new file mode 100644
index 0000000..c433d45
--- /dev/null
+++ b/embedded/mkstepper-v011/mkstepper-v011/spiport.h
@@ -0,0 +1,38 @@
+/*
+ * spiport.h
+ *
+ * Created: 2/7/2018 10:51:52 AM
+ *  Author: Jake
+ */ 
+
+
+#ifndef SPIPORT_H_
+#define SPIPORT_H_
+
+#include "sam.h"
+
+typedef struct{
+	Sercom *com;
+	PortGroup *port;
+	
+	uint32_t miso_pin;
+	uint32_t miso_bm;
+	uint32_t mosi_pin;
+	uint32_t mosi_bm;
+	uint32_t sck_pin;
+	uint32_t sck_bm;
+	uint32_t csn_pin;
+	uint32_t csn_bm;
+	
+	uint32_t apbx;
+	uint32_t peripheral;
+	uint32_t baud;
+}spiport_t;
+
+spiport_t spi_new(Sercom *com, PortGroup *port, uint32_t miso_pin, uint32_t mosi_pin, uint32_t sck_pin, uint32_t csn_pin, uint32_t apbx, uint32_t peripheral);
+
+void spi_init(spiport_t *spi, uint32_t gclknum, uint32_t gclkidcore, uint8_t baud, uint32_t dipo, uint32_t dopo);
+void spi_txchar_polled(spiport_t *spi, uint8_t data);
+void spi_txrxchar_polled(spiport_t *spi, uint8_t data, uint8_t *rxdata);
+
+#endif /* SPIPORT_H_ */
\ No newline at end of file
diff --git a/embedded/mkstepper-v011/mkstepper-v011/uartport.c b/embedded/mkstepper-v011/mkstepper-v011/uartport.c
new file mode 100644
index 0000000..3ecefeb
--- /dev/null
+++ b/embedded/mkstepper-v011/mkstepper-v011/uartport.c
@@ -0,0 +1,97 @@
+/*
+ * uartport.c
+ *
+ * Created: 2/6/2018 10:48:26 AM
+ *  Author: Jake
+ */ 
+
+#include "uartport.h"
+
+uartport_t uart_new(Sercom *com, PortGroup *port, ringbuffer_t *rbrx, ringbuffer_t *rbtx, uint32_t rx_pin, uint32_t tx_pin, uint32_t apbx, uint32_t peripheral){
+	uartport_t uart;
+	
+	uart.com = com;
+	uart.port = port;
+	
+	uart.rbrx = rbrx;
+	uart.rbtx = rbtx;
+	
+	uart.rx_pin = rx_pin;
+	uart.rx_bm = (uint32_t)(1 << rx_pin);
+	uart.tx_pin = tx_pin;
+	uart.tx_bm = (uint32_t)(1 << tx_pin);
+	uart.apbx = apbx;
+	uart.peripheral = peripheral;
+	// add ringbuffers
+	return uart;
+}
+
+void uart_init(uartport_t *uart, uint32_t gclknum, uint32_t gclkidcore, uint16_t baud){
+	// rx pin setups
+	uart->port->DIRCLR.reg = uart->rx_bm;
+	uart->port->PINCFG[uart->rx_pin].bit.PMUXEN = 1;
+	if(uart->rx_pin % 2){ // yes if odd
+		uart->port->PMUX[uart->rx_pin >> 1].reg |= PORT_PMUX_PMUXO(uart->peripheral);
+		} else {
+		uart->port->PMUX[uart->rx_pin >> 1].reg |= PORT_PMUX_PMUXE(uart->peripheral);
+	}
+	// tx pin setups
+	uart->port->DIRSET.reg = uart->tx_bm;
+	uart->port->PINCFG[uart->tx_pin].bit.PMUXEN = 1;	
+	if(uart->tx_pin % 2){ // yes if odd
+		uart->port->PMUX[uart->tx_pin >> 1].reg |= PORT_PMUX_PMUXO(uart->peripheral);
+		} else {
+		uart->port->PMUX[uart->tx_pin >> 1].reg |= PORT_PMUX_PMUXE(uart->peripheral);
+	}
+	
+	// unmask the clock
+	// -> have to do this manually b/c unfavourable api
+	GCLK->GENCTRL[gclknum].reg = GCLK_GENCTRL_SRC(GCLK_GENCTRL_SRC_DFLL) | GCLK_GENCTRL_GENEN;
+	while(GCLK->SYNCBUSY.reg & GCLK_SYNCBUSY_GENCTRL(gclknum));
+	GCLK->PCHCTRL[gclkidcore].reg = GCLK_PCHCTRL_CHEN | GCLK_PCHCTRL_GEN(gclknum);
+	// now the sercom
+	while(uart->com->USART.SYNCBUSY.bit.ENABLE);
+	uart->com->USART.CTRLA.bit.ENABLE = 0;
+	while(uart->com->USART.SYNCBUSY.bit.SWRST);
+	uart->com->USART.CTRLA.bit.SWRST = 1;
+	while(uart->com->USART.SYNCBUSY.bit.SWRST);
+	while(uart->com->USART.SYNCBUSY.bit.SWRST || SERCOM5->USART.SYNCBUSY.bit.ENABLE);
+	
+	uart->com->USART.CTRLA.reg = SERCOM_USART_CTRLA_MODE(1) | SERCOM_USART_CTRLA_DORD | SERCOM_USART_CTRLA_RXPO(1) | SERCOM_USART_CTRLA_TXPO(0);
+	while(uart->com->USART.SYNCBUSY.bit.CTRLB);
+	uart->com->USART.CTRLB.reg = SERCOM_USART_CTRLB_RXEN | SERCOM_USART_CTRLB_TXEN | SERCOM_USART_CTRLB_CHSIZE(0);
+	/*
+	BAUD = 65536*(1-S*(fBAUD/fref))
+	where S is samples per bit, 16 for async uart
+	where fBAUD is the rate that you want
+	where fref is the peripheral clock from GCLK, in this case (and most) 48MHz
+	*/
+	uart->com->USART.BAUD.reg = baud;
+	while(uart->com->USART.SYNCBUSY.bit.ENABLE);
+	uart->com->USART.CTRLA.bit.ENABLE = 1;
+	
+	uart->com->USART.INTENSET.bit.RXC = 1; // set receive interrupt on, see 34.6.4.2
+}
+
+void uart_sendchar_polled(uartport_t *uart, uint8_t data){
+	while(!uart->com->USART.INTFLAG.bit.DRE);
+	uart->com->USART.DATA.reg = data;
+}
+
+void uart_sendchar_buffered(uartport_t *uart, uint8_t data){
+	rb_putchar(uart->rbtx, data); // dump it in there
+	uart->com->USART.INTENSET.bit.DRE = 1; // set up the volley
+}
+
+void uart_rxhandler(uartport_t *uart){
+	uint8_t data = uart->com->USART.DATA.reg;
+	rb_putchar(uart->rbrx, data);
+}
+
+void uart_txhandler(uartport_t *uart){
+	if(!rb_empty(uart->rbtx)){
+		uart->com->USART.DATA.reg = rb_get(uart->rbtx);
+	} else {
+		uart->com->USART.INTENCLR.reg = SERCOM_USART_INTENCLR_DRE;
+	}
+}
\ No newline at end of file
diff --git a/embedded/mkstepper-v011/mkstepper-v011/uartport.h b/embedded/mkstepper-v011/mkstepper-v011/uartport.h
new file mode 100644
index 0000000..9551ce3
--- /dev/null
+++ b/embedded/mkstepper-v011/mkstepper-v011/uartport.h
@@ -0,0 +1,51 @@
+/*
+ * uartport.h
+ *
+ * Created: 2/6/2018 10:47:56 AM
+ *  Author: Jake
+ */ 
+
+#ifndef UARTPORT_H_
+#define UARTPORT_H_
+
+#include "sam.h"
+#include "ringbuffer.h"
+
+#define HARDWARE_IS_APBA 0
+#define HARDWARE_IS_APBB 1
+#define HARDWARE_IS_APBC 2
+#define HARDWARE_IS_APBD 3
+
+#define HARDWARE_ON_PERIPHERAL_A 0x0
+#define HARDWARE_ON_PERIPHERAL_B 0x1
+#define HARDWARE_ON_PERIPHERAL_C 0x2
+#define HARDWARE_ON_PERIPHERAL_D 0x3
+
+typedef struct{
+	Sercom *com;
+	PortGroup *port;
+	
+	ringbuffer_t *rbrx;
+	ringbuffer_t *rbtx;
+	
+	uint32_t rx_pin;
+	uint32_t rx_bm;
+	uint32_t tx_pin;
+	uint32_t tx_bm;
+	
+	uint32_t apbx;
+	uint32_t peripheral;
+	uint16_t baud;
+}uartport_t;
+
+uartport_t uart_new(Sercom *com, PortGroup *port, ringbuffer_t *rbrx, ringbuffer_t *rbtx, uint32_t rx_pin, uint32_t tx_pin, uint32_t apbx, uint32_t peripheral);
+
+void uart_init(uartport_t *uart, uint32_t gclknum, uint32_t gclkidcore, uint16_t baud);
+
+void uart_sendchar_polled(uartport_t *uart, uint8_t data);
+void uart_sendchar_buffered(uartport_t *uart, uint8_t data);
+
+void uart_rxhandler(uartport_t *uart);
+void uart_txhandler(uartport_t *uart);
+
+#endif /* UARTPORT_H_ */
\ No newline at end of file
-- 
GitLab