From 1441293cf53c04133a1c32dfc7e19ab3a03400fd Mon Sep 17 00:00:00 2001
From: Jake <jake.read@cba.mit.edu>
Date: Fri, 18 May 2018 17:05:06 -0400
Subject: [PATCH] add uartport and rb

---
 .../mkrouter-v06/mkrouter-v06/Debug/Makefile  |  24 +++-
 .../mkrouter-v06/Debug/makedep.mk             |   4 +
 embedded/mkrouter-v06/mkrouter-v06/hardware.h |  41 +++++++
 embedded/mkrouter-v06/mkrouter-v06/main.c     |  79 ++++++++++++-
 .../mkrouter-v06/mkrouter-v06.cproj           |  12 ++
 .../mkrouter-v06/mkrouter-v06/ringbuffer.c    |  71 ++++++++++++
 .../mkrouter-v06/mkrouter-v06/ringbuffer.h    |  44 ++++++++
 .../mkrouter-v06/sam_ba_monitor.c             |  26 ++++-
 .../mkrouter-v06/sam_ba_monitor.h             |   2 +
 embedded/mkrouter-v06/mkrouter-v06/uartport.c | 104 ++++++++++++++++++
 embedded/mkrouter-v06/mkrouter-v06/uartport.h |  44 ++++++++
 11 files changed, 436 insertions(+), 15 deletions(-)
 create mode 100644 embedded/mkrouter-v06/mkrouter-v06/ringbuffer.c
 create mode 100644 embedded/mkrouter-v06/mkrouter-v06/ringbuffer.h
 create mode 100644 embedded/mkrouter-v06/mkrouter-v06/uartport.c
 create mode 100644 embedded/mkrouter-v06/mkrouter-v06/uartport.h

diff --git a/embedded/mkrouter-v06/mkrouter-v06/Debug/Makefile b/embedded/mkrouter-v06/mkrouter-v06/Debug/Makefile
index c430e47..fdc3c74 100644
--- a/embedded/mkrouter-v06/mkrouter-v06/Debug/Makefile
+++ b/embedded/mkrouter-v06/mkrouter-v06/Debug/Makefile
@@ -45,10 +45,12 @@ C_SRCS +=  \
 ../Device_Startup/system_samd51.c \
 ../main.c \
 ../pin.c \
+../ringbuffer.c \
 ../sam_ba_cdc.c \
 ../sam_ba_monitor.c \
 ../sam_ba_serial.c \
-../sam_ba_usb.c
+../sam_ba_usb.c \
+../uartport.c
 
 
 PREPROCESSING_SRCS += 
@@ -65,10 +67,12 @@ Device_Startup/startup_samd51.o \
 Device_Startup/system_samd51.o \
 main.o \
 pin.o \
+ringbuffer.o \
 sam_ba_cdc.o \
 sam_ba_monitor.o \
 sam_ba_serial.o \
-sam_ba_usb.o
+sam_ba_usb.o \
+uartport.o
 
 OBJS_AS_ARGS +=  \
 board_driver_serial.o \
@@ -78,10 +82,12 @@ Device_Startup/startup_samd51.o \
 Device_Startup/system_samd51.o \
 main.o \
 pin.o \
+ringbuffer.o \
 sam_ba_cdc.o \
 sam_ba_monitor.o \
 sam_ba_serial.o \
-sam_ba_usb.o
+sam_ba_usb.o \
+uartport.o
 
 C_DEPS +=  \
 board_driver_serial.d \
@@ -91,10 +97,12 @@ Device_Startup/startup_samd51.d \
 Device_Startup/system_samd51.d \
 main.d \
 pin.d \
+ringbuffer.d \
 sam_ba_cdc.d \
 sam_ba_monitor.d \
 sam_ba_serial.d \
-sam_ba_usb.d
+sam_ba_usb.d \
+uartport.d
 
 C_DEPS_AS_ARGS +=  \
 board_driver_serial.d \
@@ -104,10 +112,12 @@ Device_Startup/startup_samd51.d \
 Device_Startup/system_samd51.d \
 main.d \
 pin.d \
+ringbuffer.d \
 sam_ba_cdc.d \
 sam_ba_monitor.d \
 sam_ba_serial.d \
-sam_ba_usb.d
+sam_ba_usb.d \
+uartport.d
 
 OUTPUT_FILE_PATH +=mkrouter-v06.elf
 
@@ -143,6 +153,10 @@ LINKER_SCRIPT_DEP+=  \
 
 
 
+
+
+
+
 
 
 
diff --git a/embedded/mkrouter-v06/mkrouter-v06/Debug/makedep.mk b/embedded/mkrouter-v06/mkrouter-v06/Debug/makedep.mk
index 076dc79..d406fca 100644
--- a/embedded/mkrouter-v06/mkrouter-v06/Debug/makedep.mk
+++ b/embedded/mkrouter-v06/mkrouter-v06/Debug/makedep.mk
@@ -16,6 +16,8 @@ main.c
 
 pin.c
 
+ringbuffer.c
+
 sam_ba_cdc.c
 
 sam_ba_monitor.c
@@ -24,3 +26,5 @@ sam_ba_serial.c
 
 sam_ba_usb.c
 
+uartport.c
+
diff --git a/embedded/mkrouter-v06/mkrouter-v06/hardware.h b/embedded/mkrouter-v06/mkrouter-v06/hardware.h
index fdf9962..4195160 100644
--- a/embedded/mkrouter-v06/mkrouter-v06/hardware.h
+++ b/embedded/mkrouter-v06/mkrouter-v06/hardware.h
@@ -12,6 +12,20 @@
 #define HARDWARE_H_
 
 #include "pin.h"
+#include "ringbuffer.h"
+#include "uartport.h"
+
+// For if-case init
+
+#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
 
 /* USB PINS
 
@@ -39,6 +53,10 @@ UP0STLB		PB22	(on receive)
 UP0STLR		PB31	(on transmit)
 */
 
+ringbuffer_t up0rbrx;
+ringbuffer_t up0rbtx;
+
+uartport_t up0;
 
 pin_t up0stlb;
 pin_t up0stlr;
@@ -51,6 +69,10 @@ UP1STLB		PA20
 UP1STLR		PA21
 */
 
+ringbuffer_t up1rbrx;
+ringbuffer_t up1rbtx;
+
+uartport_t up1;
 
 pin_t up1stlb;
 pin_t up1stlr;
@@ -62,6 +84,10 @@ UP2STLB		PB16
 UP2STLR		PB17 
 */
 
+ringbuffer_t up2rbrx;
+ringbuffer_t up2rbtx;
+
+uartport_t up2;
 
 pin_t up2stlb;
 pin_t up2stlr;
@@ -73,6 +99,10 @@ UP3STLB		PA18
 UP3STLR		PA19
 */
 
+ringbuffer_t up3rbrx;
+ringbuffer_t up3rbtx;
+
+uartport_t up3;
 
 pin_t up3stlb;
 pin_t up3stlr;
@@ -84,6 +114,10 @@ UP4STLB		PA14
 UP4STLR		PA15 
 */
 
+ringbuffer_t up4rbrx;
+ringbuffer_t up4rbtx;
+
+uartport_t up4;
 
 pin_t up4stlb;
 pin_t up4stlr;
@@ -95,9 +129,16 @@ UP5STLB		PB13
 UP5STLR		PB14
 */
 
+ringbuffer_t up5rbrx;
+ringbuffer_t up5rbtx;
+
+uartport_t up5;
 
 pin_t up5stlb;
 pin_t up5stlr;
 
+// pointers to uarports
+#define NUM_UPS 6
+uartport_t *ups[NUM_UPS];
 
 #endif /* HARDWARE_H_ */
\ No newline at end of file
diff --git a/embedded/mkrouter-v06/mkrouter-v06/main.c b/embedded/mkrouter-v06/mkrouter-v06/main.c
index eee87c2..5df55ee 100644
--- a/embedded/mkrouter-v06/mkrouter-v06/main.c
+++ b/embedded/mkrouter-v06/mkrouter-v06/main.c
@@ -69,6 +69,60 @@ void lights_init(void){
 	pin_set(&up5stlr);
 }
 
+void uarts_init(void){
+	// don't forget to also add the handler
+	NVIC_EnableIRQ(SERCOM0_0_IRQn);
+	NVIC_EnableIRQ(SERCOM0_2_IRQn);
+	
+	// init rbs
+	rb_init(&up0rbrx);
+	rb_init(&up0rbtx);
+	
+	// init uart 
+	up0 = uart_new(SERCOM0, &PORT->Group[0], &up0rbrx, &up0rbtx, 5, 4);
+	MCLK->APBAMASK.reg |= MCLK_APBAMASK_SERCOM0;
+	uart_init(&up0, 7, SERCOM0_GCLK_ID_CORE, 63018, HARDWARE_ON_PERIPHERAL_D);
+	
+	
+	
+	// init rbs
+	rb_init(&up1rbrx);
+	rb_init(&up1rbtx);
+	
+	
+	
+	// init rbs
+	rb_init(&up2rbrx);
+	rb_init(&up2rbtx);
+	
+	
+	
+	
+	// init rbs
+	rb_init(&up3rbrx);
+	rb_init(&up3rbtx);
+	
+	
+	
+	
+	// init rbs
+	rb_init(&up4rbrx);
+	rb_init(&up4rbtx);
+	
+	
+	// init rbs
+	rb_init(&up5rbrx);
+	rb_init(&up5rbtx);
+	
+	// now pack all into ups
+	ups[0] = &up0;
+	ups[1] = &up1;
+	ups[2] = &up2;
+	ups[3] = &up3;
+	ups[4] = &up4;
+	ups[5] = &up5;
+}
+
 static volatile bool main_b_cdc_enable = false;
 
 int main(void)
@@ -81,6 +135,9 @@ int main(void)
 	__enable_irq();
 	
 	lights_init();
+	
+	// init uartports
+	uarts_init();
 		
 	// pointer to the USB struct in sam_ba_usb.h
 	P_USB_CDC pCdc; 
@@ -94,22 +151,26 @@ int main(void)
     /* Replace with your application code */
     while (1) 
     {
-
 		// waits for config to config
 		if(pCdc->IsConfigured(pCdc) != 0){
 			main_b_cdc_enable = true;
-			pin_clear(&stlUsb);
 		}
 		
+		uint8_t testUart[3] = {12,24,48};
+		
 		// if config is config, and port is opened
 		if(main_b_cdc_enable){
 			sam_ba_monitor_init(SAM_BA_INTERFACE_USBCDC);
 			// loops on this
 			while(1){
 				sam_ba_monitor_run();
-				// @ HERE: understand how this /\ runs, looks through buffer etc... 
-				// do the same for (1) bytes -> uart
-				// (2) for packet searching
+				for(int i = 0; i < NUM_UPS; i ++){	
+					while(!rb_empty(up0.rbrx)){
+						uart_sendchar_buffered(&up0, rb_get(up0.rbrx));
+					}
+				}
+				//uart_sendchars_buffered(&up0, &testUart, 3);
+				// apaport loops
 			}
 			
 		}
@@ -138,3 +199,11 @@ void SysTick_Handler(void){
 	*/
 	// monitor_sys_tick
 }
+
+void SERCOM0_0_Handler(void){
+	uart_txhandler(&up0);
+}
+
+void SERCOM0_2_Handler(void){
+	uart_rxhandler(&up0);
+}
\ No newline at end of file
diff --git a/embedded/mkrouter-v06/mkrouter-v06/mkrouter-v06.cproj b/embedded/mkrouter-v06/mkrouter-v06/mkrouter-v06.cproj
index 26fc1eb..88e975f 100644
--- a/embedded/mkrouter-v06/mkrouter-v06/mkrouter-v06.cproj
+++ b/embedded/mkrouter-v06/mkrouter-v06/mkrouter-v06.cproj
@@ -195,6 +195,12 @@
     <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="sam_ba_cdc.c">
       <SubType>compile</SubType>
     </Compile>
@@ -219,6 +225,12 @@
     <Compile Include="sam_ba_usb.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\" />
diff --git a/embedded/mkrouter-v06/mkrouter-v06/ringbuffer.c b/embedded/mkrouter-v06/mkrouter-v06/ringbuffer.c
new file mode 100644
index 0000000..eeb5367
--- /dev/null
+++ b/embedded/mkrouter-v06/mkrouter-v06/ringbuffer.c
@@ -0,0 +1,71 @@
+/*
+ * 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){
+	// read from tail, update at head
+	// if head is 'just behind' tail (in ring) we have no extra space: the
+	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){
+		// rb_freespace, not working?
+		return 0;
+	} else {
+		*/
+	for(int i = 0; i < size; i ++){
+		rb_putchar(rb, data[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/mkrouter-v06/mkrouter-v06/ringbuffer.h b/embedded/mkrouter-v06/mkrouter-v06/ringbuffer.h
new file mode 100644
index 0000000..889caf9
--- /dev/null
+++ b/embedded/mkrouter-v06/mkrouter-v06/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/mkrouter-v06/mkrouter-v06/sam_ba_monitor.c b/embedded/mkrouter-v06/mkrouter-v06/sam_ba_monitor.c
index 79c5ede..c5c4869 100644
--- a/embedded/mkrouter-v06/mkrouter-v06/sam_ba_monitor.c
+++ b/embedded/mkrouter-v06/mkrouter-v06/sam_ba_monitor.c
@@ -27,6 +27,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 #include "sam_ba_cdc.h"
 //#include "board_driver_led.h"
 
+#include "hardware.h"
+
 const char RomBOOT_Version[] = SAM_BA_VERSION;
 const char RomBOOT_ExtendedCapabilities[] = "[Arduino:XYZ]";
 
@@ -277,19 +279,33 @@ static void sam_ba_monitor_loop(void)
 {
 	// get bytes, handle.. 
 	length = sam_ba_getdata(ptr_monitor_if, data, SIZEBUFMAX);
+	pin_clear(&stlPacket);
+
 	if(length > 0 && !usbComOpen){
 		usbComOpen = 1;
+		pin_clear(&stlUsb);
 	}
 	
 	// reply
 	sam_ba_putdata(ptr_monitor_if, data, length);
 	
+	// have to implement APA code here? and watch for multipackets?
+	for(int i = 0; i < length; i ++, ptr++){
+		// apa 
+	}
+	pin_set(&stlPacket);
+	
 	// dirt nasty heartbeat
+	/*
 	if(!(tick % 100000)){
 		sam_ba_putdata(ptr_monitor_if, &data_out, 3);
 	}
 	tick ++;
-	
+	*/
+}
+
+void sam_ba_port_put_data(uint8_t *data, uint32_t length){
+	sam_ba_putdata(ptr_monitor_if, data, length);
 }
 
 void sam_ba_monitor_sys_tick(void)
@@ -308,6 +324,7 @@ void sam_ba_monitor_sys_tick(void)
 */
 void sam_ba_monitor_run(void)
 {
+	/*
 	uint32_t pageSizes[] = { 8, 16, 32, 64, 128, 256, 512, 1024 };
 	PAGE_SIZE = pageSizes[NVMCTRL->PARAM.bit.PSZ];
 	PAGES = NVMCTRL->PARAM.bit.NVMP;
@@ -315,8 +332,7 @@ void sam_ba_monitor_run(void)
 
 	ptr_data = NULL;
 	command = 'z';
-	while (1)
-	{
-		sam_ba_monitor_loop();
-	}
+	*/
+
+	sam_ba_monitor_loop();
 }
diff --git a/embedded/mkrouter-v06/mkrouter-v06/sam_ba_monitor.h b/embedded/mkrouter-v06/mkrouter-v06/sam_ba_monitor.h
index 6cfa4db..d42375b 100644
--- a/embedded/mkrouter-v06/mkrouter-v06/sam_ba_monitor.h
+++ b/embedded/mkrouter-v06/mkrouter-v06/sam_ba_monitor.h
@@ -57,6 +57,8 @@ void sam_ba_monitor_sys_tick(void);
  */
 void sam_ba_monitor_run(void);
 
+void sam_ba_port_put_data(uint8_t *data, uint32_t length);
+
 /**
  * \brief
  *
diff --git a/embedded/mkrouter-v06/mkrouter-v06/uartport.c b/embedded/mkrouter-v06/mkrouter-v06/uartport.c
new file mode 100644
index 0000000..aef6907
--- /dev/null
+++ b/embedded/mkrouter-v06/mkrouter-v06/uartport.c
@@ -0,0 +1,104 @@
+/*
+ * uartport.c
+ *
+ * Created: 2/6/2018 10:48:26 AM
+ *  Author: Jake
+ */ 
+
+#include "uartport.h"
+#include "hardware.h"
+
+uartport_t uart_new(Sercom *com, PortGroup *port, ringbuffer_t *rbrx, ringbuffer_t *rbtx, uint32_t rx_pin, uint32_t tx_pin){
+	uartport_t uart;
+	
+	// pointers to com and port
+	uart.com = com;
+	uart.port = port;
+	
+	// add ringbuffers
+	uart.rbrx = rbrx;
+	uart.rbtx = rbtx;
+	
+	// pins 
+	uart.pinrx = rx_pin;
+	uart.pinrx_bm = (uint32_t)(1 << rx_pin);
+	uart.pintx = tx_pin;
+	uart.pintx_bm = (uint32_t)(1 << tx_pin);
+	
+	return uart;
+}
+
+void uart_init(uartport_t *uart, uint32_t gclknum, uint32_t gclkidcore, uint16_t baud, uint32_t peripheral){
+	// rx pin setups
+	uart->port->DIRCLR.reg = uart->pinrx_bm;
+	uart->port->PINCFG[uart->pinrx].bit.PMUXEN = 1;
+	if(uart->pinrx % 2){ // yes if odd
+		uart->port->PMUX[uart->pinrx >> 1].reg |= PORT_PMUX_PMUXO(peripheral);
+		} else {
+		uart->port->PMUX[uart->pinrx >> 1].reg |= PORT_PMUX_PMUXE(peripheral);
+	}
+	// tx pin setups
+	uart->port->DIRSET.reg = uart->pintx_bm;
+	uart->port->PINCFG[uart->pintx].bit.PMUXEN = 1;	
+	if(uart->pintx % 2){ // yes if odd
+		uart->port->PMUX[uart->pintx >> 1].reg |= PORT_PMUX_PMUXO(peripheral);
+		} else {
+		uart->port->PMUX[uart->pintx >> 1].reg |= PORT_PMUX_PMUXE(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_sendchars_buffered(uartport_t *uart, uint8_t *data, uint8_t length){
+	rb_putdata(uart->rbtx, data, length);
+	uart->com->USART.INTENSET.bit.DRE = 1;
+}
+
+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/mkrouter-v06/mkrouter-v06/uartport.h b/embedded/mkrouter-v06/mkrouter-v06/uartport.h
new file mode 100644
index 0000000..be3da15
--- /dev/null
+++ b/embedded/mkrouter-v06/mkrouter-v06/uartport.h
@@ -0,0 +1,44 @@
+/*
+ * uartport.h
+ *
+ * Created: 2/6/2018 10:47:56 AM
+ *  Author: Jake
+ */ 
+
+#ifndef UARTPORT_H_
+#define UARTPORT_H_
+
+#include "sam.h"
+#include "ringbuffer.h"
+#include "pin.h"
+
+typedef struct{
+	Sercom *com;
+	PortGroup *port;
+	
+	uint32_t pinrx;
+	uint32_t pinrx_bm;
+	uint32_t pintx;
+	uint32_t pintx_bm;
+	
+	ringbuffer_t *rbrx;
+	ringbuffer_t *rbtx;
+	
+	pin_t *stlr;
+	pin_t *stlb;
+
+	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);
+
+void uart_init(uartport_t *uart, uint32_t gclknum, uint32_t gclkidcore, uint16_t baud, uint32_t peripheral);
+
+void uart_sendchar_polled(uartport_t *uart, uint8_t data);
+void uart_sendchar_buffered(uartport_t *uart, uint8_t data);
+void uart_sendchars_buffered(uartport_t *uart, uint8_t *data, uint8_t length);
+
+void uart_rxhandler(uartport_t *uart);
+void uart_txhandler(uartport_t *uart);
+
+#endif /* UARTPORT_H_ */
\ No newline at end of file
-- 
GitLab