From 48d5c0f77edb1c350ce74020424d4a25b235bd6f Mon Sep 17 00:00:00 2001
From: Jake <jake.read@cba.mit.edu>
Date: Thu, 12 Jul 2018 02:40:51 -0400
Subject: [PATCH] firmware alive, replies to test

---
 circuit/README.md                             |   2 +
 circuit/atkbldcdriver/atkbldcdriver.brd       |  83 +++---
 circuit/atkbldcdriver/atkbldcdriver.sch       |  50 ++--
 circuit/atkbldcdriver/eagle.epf               |  12 +-
 embedded/README.md                            |   5 +
 embedded/atkbldcdriver/atkbldcdriver.atsln    |  22 ++
 .../atkbldcdriver/Debug/Makefile              | 185 +++++++++++++
 .../atkbldcdriver/Debug/atkbldcdriver.eep     |   1 +
 .../atkbldcdriver/Debug/makedep.mk            |  22 ++
 .../atkbldcdriver/atkbldcdriver/ams5047.c     |  40 +++
 .../atkbldcdriver/atkbldcdriver/ams5047.h     |  38 +++
 .../atkbldcdriver.componentinfo.xml           |  86 ++++++
 .../atkbldcdriver/atkbldcdriver.cproj         | 195 ++++++++++++++
 .../atkbldcdriver/atkbldcdriver/atkhandler.c  | 164 ++++++++++++
 .../atkbldcdriver/atkbldcdriver/atkhandler.h  |  32 +++
 .../atkbldcdriver/atkbldcdriver/atkport.c     | 123 +++++++++
 .../atkbldcdriver/atkbldcdriver/atkport.h     |  47 ++++
 .../atkbldcdriver/atkbldcdriver/fastmath.c    |  11 +
 .../atkbldcdriver/atkbldcdriver/fastmath.h    |  14 +
 .../atkbldcdriver/atkbldcdriver/hardware.h    |  68 +++++
 embedded/atkbldcdriver/atkbldcdriver/main.c   | 130 +++++++++
 embedded/atkbldcdriver/atkbldcdriver/pin.c    |  49 ++++
 embedded/atkbldcdriver/atkbldcdriver/pin.h    |  34 +++
 .../atkbldcdriver/atkbldcdriver/ringbuffer.c  |  72 +++++
 .../atkbldcdriver/atkbldcdriver/ringbuffer.h  |  43 +++
 .../atkbldcdriver/atkbldcdriver/spiport.c     |  54 ++++
 .../atkbldcdriver/atkbldcdriver/spiport.h     |  35 +++
 .../atkbldcdriver/atkbldcdriver/stepper.c     | 247 ++++++++++++++++++
 .../atkbldcdriver/atkbldcdriver/stepper.h     |  95 +++++++
 .../atkbldcdriver/atkbldcdriver/uartport.c    |  70 +++++
 .../atkbldcdriver/atkbldcdriver/uartport.h    |  42 +++
 31 files changed, 2006 insertions(+), 65 deletions(-)
 create mode 100644 embedded/atkbldcdriver/atkbldcdriver.atsln
 create mode 100644 embedded/atkbldcdriver/atkbldcdriver/Debug/Makefile
 create mode 100644 embedded/atkbldcdriver/atkbldcdriver/Debug/atkbldcdriver.eep
 create mode 100644 embedded/atkbldcdriver/atkbldcdriver/Debug/makedep.mk
 create mode 100644 embedded/atkbldcdriver/atkbldcdriver/ams5047.c
 create mode 100644 embedded/atkbldcdriver/atkbldcdriver/ams5047.h
 create mode 100644 embedded/atkbldcdriver/atkbldcdriver/atkbldcdriver.componentinfo.xml
 create mode 100644 embedded/atkbldcdriver/atkbldcdriver/atkbldcdriver.cproj
 create mode 100644 embedded/atkbldcdriver/atkbldcdriver/atkhandler.c
 create mode 100644 embedded/atkbldcdriver/atkbldcdriver/atkhandler.h
 create mode 100644 embedded/atkbldcdriver/atkbldcdriver/atkport.c
 create mode 100644 embedded/atkbldcdriver/atkbldcdriver/atkport.h
 create mode 100644 embedded/atkbldcdriver/atkbldcdriver/fastmath.c
 create mode 100644 embedded/atkbldcdriver/atkbldcdriver/fastmath.h
 create mode 100644 embedded/atkbldcdriver/atkbldcdriver/hardware.h
 create mode 100644 embedded/atkbldcdriver/atkbldcdriver/main.c
 create mode 100644 embedded/atkbldcdriver/atkbldcdriver/pin.c
 create mode 100644 embedded/atkbldcdriver/atkbldcdriver/pin.h
 create mode 100644 embedded/atkbldcdriver/atkbldcdriver/ringbuffer.c
 create mode 100644 embedded/atkbldcdriver/atkbldcdriver/ringbuffer.h
 create mode 100644 embedded/atkbldcdriver/atkbldcdriver/spiport.c
 create mode 100644 embedded/atkbldcdriver/atkbldcdriver/spiport.h
 create mode 100644 embedded/atkbldcdriver/atkbldcdriver/stepper.c
 create mode 100644 embedded/atkbldcdriver/atkbldcdriver/stepper.h
 create mode 100644 embedded/atkbldcdriver/atkbldcdriver/uartport.c
 create mode 100644 embedded/atkbldcdriver/atkbldcdriver/uartport.h

diff --git a/circuit/README.md b/circuit/README.md
index 4e69a71..0d295ea 100644
--- a/circuit/README.md
+++ b/circuit/README.md
@@ -10,6 +10,8 @@ Power is bussed to the board with two M3 Screw Terminals. The board includes roo
 
 ## Notes
 
+ - label lights 
+
  - might have to go to DRV8320 - newer, available
   - CSD88548 is CSD88599 but more amps less volts, use these 
  - use RDT RTD for BLDC -  223-1563-1-ND
diff --git a/circuit/atkbldcdriver/atkbldcdriver.brd b/circuit/atkbldcdriver/atkbldcdriver.brd
index d2c3429..0d39a75 100644
--- a/circuit/atkbldcdriver/atkbldcdriver.brd
+++ b/circuit/atkbldcdriver/atkbldcdriver.brd
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!DOCTYPE eagle SYSTEM "eagle.dtd">
-<eagle version="9.0.0">
+<eagle version="9.1.1">
 <drawing>
 <settings>
 <setting alwaysvectorfont="no"/>
@@ -226,6 +226,9 @@ they cannot often be in them</text>
 <wire x1="35.5" y1="12.5" x2="32" y2="16" width="0.1524" layer="20" curve="-90"/>
 <dimension x1="32" y1="63.5" x2="100.5" y2="63.5" x3="66.25" y3="67.5" textsize="0.6096" textratio="10" layer="47"/>
 <dimension x1="102.5" y1="62" x2="102.5" y2="12.5" x3="107" y3="37.25" textsize="0.6096" textratio="10" layer="47"/>
+<dimension x1="35.5" y1="58.5" x2="76" y2="58.5" x3="55.75" y3="71" textsize="0.6096" textratio="10" layer="47"/>
+<dimension x1="35.5" y1="58.5" x2="35.5" y2="16" x3="28" y3="37.25" textsize="0.6096" textratio="10" layer="47"/>
+<dimension x1="35.5" y1="58.5" x2="32" y2="58.5" x3="33.75" y3="65.5" textsize="0.6096" textratio="10" layer="47"/>
 </plain>
 <libraries>
 <library name="fab">
@@ -959,6 +962,9 @@ design rules under a new name.</description>
 <param name="checkRestrict" value="1"/>
 <param name="checkStop" value="0"/>
 <param name="checkValues" value="0"/>
+<param name="checkNames" value="1"/>
+<param name="checkWireStubs" value="1"/>
+<param name="checkPolygonWidth" value="0"/>
 <param name="useDiameter" value="13"/>
 <param name="maxErrors" value="50"/>
 </designrules>
@@ -3123,18 +3129,6 @@ design rules under a new name.</description>
 <wire x1="48.65" y1="51.71894375" x2="48.65" y2="51.1" width="0.1524" layer="1"/>
 <wire x1="49.02625625" y1="52.0952" x2="48.65" y2="51.71894375" width="0.1524" layer="1"/>
 </signal>
-<signal name="EN-GATE">
-<contactref element="U2" pad="P$16"/>
-<contactref element="S3" pad="P$2"/>
-<contactref element="S3" pad="P$5"/>
-<wire x1="66.000009375" y1="46" x2="64.5232875" y2="46" width="0.1524" layer="1"/>
-<wire x1="64.5232875" y1="46" x2="64.1946875" y2="45.6714" width="0.1524" layer="1"/>
-<wire x1="61.4053125" y1="45.6714" x2="61.2" y2="45.8767125" width="0.1524" layer="1"/>
-<wire x1="64.1946875" y1="45.6714" x2="61.4053125" y2="45.6714" width="0.1524" layer="1"/>
-<wire x1="61.2" y1="57.488" x2="61.66" y2="57.948" width="0.1524" layer="1"/>
-<wire x1="61.2" y1="45.8767125" x2="61.2" y2="57.488" width="0.1524" layer="1"/>
-<wire x1="61.66" y1="57.948" x2="61.66" y2="60.748" width="0.1524" layer="1"/>
-</signal>
 <signal name="V-W">
 <contactref element="R37" pad="2"/>
 <contactref element="R36" pad="1"/>
@@ -3194,27 +3188,6 @@ design rules under a new name.</description>
 <wire x1="47.15" y1="51.1" x2="47.15" y2="51.58105625" width="0.1524" layer="1"/>
 <wire x1="47.15" y1="51.58105625" x2="47.74514375" y2="52.1762" width="0.1524" layer="1"/>
 </signal>
-<signal name="EN-GATE-MC">
-<contactref element="S3" pad="P$1"/>
-<contactref element="S3" pad="P$4"/>
-<wire x1="64.16" y1="57.948" x2="64.16" y2="60.748" width="0.1524" layer="1"/>
-<via x="64.16" y="57.948" extent="1-16" drill="0.3"/>
-<wire x1="64.16" y1="57.948" x2="58.048" y2="57.948" width="0.1524" layer="16"/>
-<wire x1="58.048" y1="57.948" x2="56.5048" y2="56.4048" width="0.1524" layer="16"/>
-<wire x1="56.5048" y1="56.4048" x2="55.47374375" y2="56.4048" width="0.1524" layer="16"/>
-<via x="44.1428" y="52.3" extent="1-16" drill="0.3"/>
-<contactref element="U1" pad="27"/>
-<wire x1="44.65" y1="51.1" x2="44.65" y2="51.59905" width="0.1524" layer="1"/>
-<wire x1="44.65" y1="51.59905" x2="44.369" y2="51.88005" width="0.1524" layer="1"/>
-<wire x1="44.369" y1="51.88005" x2="44.369" y2="52.0738" width="0.1524" layer="1"/>
-<wire x1="44.369" y1="52.0738" x2="44.1428" y2="52.3" width="0.1524" layer="1"/>
-<wire x1="55.47374375" y1="56.4048" x2="53.17374375" y2="54.1048" width="0.1524" layer="16"/>
-<wire x1="53.17374375" y1="54.1048" x2="46.47374375" y2="54.1048" width="0.1524" layer="16"/>
-<wire x1="44.99994375" y1="52.631" x2="44.68005" y2="52.631" width="0.1524" layer="16"/>
-<wire x1="44.34905" y1="52.3" x2="44.1428" y2="52.3" width="0.1524" layer="16"/>
-<wire x1="44.68005" y1="52.631" x2="44.34905" y2="52.3" width="0.1524" layer="16"/>
-<wire x1="46.47374375" y1="54.1048" x2="44.99994375" y2="52.631" width="0.1524" layer="16"/>
-</signal>
 <signal name="N$26">
 <contactref element="S3" pad="P$3"/>
 <contactref element="R3" pad="1"/>
@@ -3631,7 +3604,49 @@ design rules under a new name.</description>
 <wire x1="46.2214" y1="29.7738" x2="46.2214" y2="20.4714" width="0.1524" layer="16"/>
 <wire x1="46.96" y1="31.4332875" x2="45.9952" y2="30.4684875" width="0.1524" layer="1"/>
 </signal>
+<signal name="DRV_EN">
+<contactref element="S3" pad="P$1"/>
+<contactref element="S3" pad="P$4"/>
+<wire x1="56.5048" y1="56.4048" x2="58.048" y2="57.948" width="0.1524" layer="16"/>
+<wire x1="56.5048" y1="56.4048" x2="55.47374375" y2="56.4048" width="0.1524" layer="16"/>
+<via x="44.1428" y="52.3" extent="1-16" drill="0.3"/>
+<contactref element="U1" pad="27"/>
+<wire x1="44.65" y1="51.1" x2="44.65" y2="51.59905" width="0.1524" layer="1"/>
+<wire x1="44.65" y1="51.59905" x2="44.369" y2="51.88005" width="0.1524" layer="1"/>
+<wire x1="44.369" y1="51.88005" x2="44.369" y2="52.0738" width="0.1524" layer="1"/>
+<wire x1="44.369" y1="52.0738" x2="44.1428" y2="52.3" width="0.1524" layer="1"/>
+<wire x1="55.47374375" y1="56.4048" x2="53.17374375" y2="54.1048" width="0.1524" layer="16"/>
+<wire x1="53.17374375" y1="54.1048" x2="46.47374375" y2="54.1048" width="0.1524" layer="16"/>
+<wire x1="44.99994375" y1="52.631" x2="44.68005" y2="52.631" width="0.1524" layer="16"/>
+<wire x1="44.34905" y1="52.3" x2="44.1428" y2="52.3" width="0.1524" layer="16"/>
+<wire x1="44.68005" y1="52.631" x2="44.34905" y2="52.3" width="0.1524" layer="16"/>
+<wire x1="46.47374375" y1="54.1048" x2="44.99994375" y2="52.631" width="0.1524" layer="16"/>
+<wire x1="64.16" y1="60.748" x2="64.16" y2="57.948" width="0.1524" layer="1"/>
+<via x="64" y="58" extent="1-16" drill="0.3"/>
+<wire x1="58.048" y1="57.948" x2="63.948" y2="57.948" width="0.1524" layer="16"/>
+<wire x1="63.948" y1="57.948" x2="64" y2="58" width="0.1524" layer="16"/>
+<wire x1="64" y1="58" x2="64.16" y2="57.948" width="0" layer="19" extent="1-1"/>
+</signal>
+<signal name="DRV_EN_DRV">
+<contactref element="S3" pad="P$2"/>
+<contactref element="S3" pad="P$5"/>
+<wire x1="61.66" y1="57.948" x2="61.66" y2="60.748" width="0.1524" layer="1"/>
+<contactref element="U2" pad="P$16"/>
+<wire x1="66.000009375" y1="46" x2="64.5232875" y2="46" width="0.1524" layer="1"/>
+<wire x1="64.5232875" y1="46" x2="64.1946875" y2="45.6714" width="0.1524" layer="1"/>
+<wire x1="61.4053125" y1="45.6714" x2="61.2" y2="45.8767125" width="0.1524" layer="1"/>
+<wire x1="64.1946875" y1="45.6714" x2="61.4053125" y2="45.6714" width="0.1524" layer="1"/>
+<wire x1="61.2" y1="45.8767125" x2="61.2" y2="57.488" width="0.1524" layer="1"/>
+<wire x1="61.2" y1="57.488" x2="61.66" y2="57.948" width="0" layer="19" extent="1-1"/>
+</signal>
 </signals>
+<mfgpreviewcolors>
+<mfgpreviewcolor name="soldermaskcolor" color="0xC8008000"/>
+<mfgpreviewcolor name="silkscreencolor" color="0xFFFEFEFE"/>
+<mfgpreviewcolor name="backgroundcolor" color="0xFF282828"/>
+<mfgpreviewcolor name="coppercolor" color="0xFFFFBF00"/>
+<mfgpreviewcolor name="substratecolor" color="0xFF786E46"/>
+</mfgpreviewcolors>
 </board>
 </drawing>
 <compatibility>
diff --git a/circuit/atkbldcdriver/atkbldcdriver.sch b/circuit/atkbldcdriver/atkbldcdriver.sch
index 1b6584d..9b1145a 100644
--- a/circuit/atkbldcdriver/atkbldcdriver.sch
+++ b/circuit/atkbldcdriver/atkbldcdriver.sch
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!DOCTYPE eagle SYSTEM "eagle.dtd">
-<eagle version="9.0.0">
+<eagle version="9.1.1">
 <drawing>
 <settings>
 <setting alwaysvectorfont="no"/>
@@ -5572,18 +5572,6 @@ high speed (Philips)</description>
 <label x="-48.26" y="63.5" size="1.778" layer="95"/>
 </segment>
 </net>
-<net name="EN-GATE" class="0">
-<segment>
-<pinref part="U2" gate="G$1" pin="EN_GATE"/>
-<wire x1="78.74" y1="30.48" x2="60.96" y2="30.48" width="0.1524" layer="91"/>
-<label x="60.96" y="30.48" size="1.778" layer="95"/>
-</segment>
-<segment>
-<pinref part="S3" gate="G$1" pin="2"/>
-<wire x1="-60.96" y1="134.62" x2="-50.8" y2="134.62" width="0.1524" layer="91"/>
-<label x="-58.42" y="134.62" size="1.778" layer="95"/>
-</segment>
-</net>
 <net name="V-W" class="0">
 <segment>
 <pinref part="R37" gate="G$1" pin="2"/>
@@ -5629,18 +5617,6 @@ high speed (Philips)</description>
 <label x="-48.26" y="55.88" size="1.778" layer="95"/>
 </segment>
 </net>
-<net name="EN-GATE-MC" class="0">
-<segment>
-<pinref part="S3" gate="G$1" pin="1"/>
-<wire x1="-71.12" y1="132.08" x2="-86.36" y2="132.08" width="0.1524" layer="91"/>
-<label x="-86.36" y="132.08" size="1.778" layer="95"/>
-</segment>
-<segment>
-<pinref part="U1" gate="G$1" pin="PD1/XCK0"/>
-<wire x1="-50.8" y1="45.72" x2="-33.02" y2="45.72" width="0.1524" layer="91"/>
-<label x="-48.26" y="45.72" size="1.778" layer="95"/>
-</segment>
-</net>
 <net name="N$26" class="0">
 <segment>
 <pinref part="S3" gate="G$1" pin="3"/>
@@ -5980,6 +5956,30 @@ high speed (Philips)</description>
 <wire x1="-109.22" y1="121.92" x2="-124.46" y2="121.92" width="0.1524" layer="91"/>
 </segment>
 </net>
+<net name="DRV_EN" class="0">
+<segment>
+<pinref part="S3" gate="G$1" pin="1"/>
+<wire x1="-71.12" y1="132.08" x2="-86.36" y2="132.08" width="0.1524" layer="91"/>
+<label x="-86.36" y="132.08" size="1.778" layer="95"/>
+</segment>
+<segment>
+<pinref part="U1" gate="G$1" pin="PD1/XCK0"/>
+<wire x1="-50.8" y1="45.72" x2="-33.02" y2="45.72" width="0.1524" layer="91"/>
+<label x="-48.26" y="45.72" size="1.778" layer="95"/>
+</segment>
+</net>
+<net name="DRV_EN_DRV" class="0">
+<segment>
+<pinref part="S3" gate="G$1" pin="2"/>
+<wire x1="-60.96" y1="134.62" x2="-50.8" y2="134.62" width="0.1524" layer="91"/>
+<label x="-58.42" y="134.62" size="1.778" layer="95"/>
+</segment>
+<segment>
+<pinref part="U2" gate="G$1" pin="EN_GATE"/>
+<wire x1="78.74" y1="30.48" x2="60.96" y2="30.48" width="0.1524" layer="91"/>
+<label x="60.96" y="30.48" size="1.778" layer="95"/>
+</segment>
+</net>
 </nets>
 </sheet>
 </sheets>
diff --git a/circuit/atkbldcdriver/eagle.epf b/circuit/atkbldcdriver/eagle.epf
index 303d69e..0ef4ef7 100644
--- a/circuit/atkbldcdriver/eagle.epf
+++ b/circuit/atkbldcdriver/eagle.epf
@@ -1,5 +1,5 @@
 [Eagle]
-Version="09 00 00"
+Version="09 01 01"
 Platform="Windows"
 Globals="Globals"
 Desktop="Desktop"
@@ -42,7 +42,7 @@ UsedLibrary="D:/Dropbox (Personal)/CBA/doc/libraries_jake/eagle/sparkfun/SparkFu
 Type="Board Editor"
 Number=1
 File="atkbldcdriver.brd"
-View="38.026 5.39031 118.602 72.4968"
+View="46.0222 19.7572 101.977 66.359"
 WireWidths=" 0.0762 0.127 0.15 0.508 0.6096 0.8128 2.54 1.016 1.27 0.3048 0.254 0.2 0.4064 0.1016 0.2032 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.35 0.4 0.45 0.5 0.55 0.65 0.7 0.75 0.8 0.85 0.9 1 0.6 0.3"
@@ -58,7 +58,7 @@ DimensionExtWidths=" 0.127 0.254 0.1 0.13 0.26 0"
 DimensionExtLengths=" 1.27 2.54 1 2 3 0"
 DimensionExtOffsets=" 1.27 2.54 1 2 3 0"
 SmdSizes=" 0.3048 0.1524 0.4064 0.2032 0.6096 0.3048 0.8128 0.4064 1.016 0.508 1.27 0.6604 1.4224 0.7112 1.6764 0.8128 1.778 0.9144 1.9304 0.9652 2.1844 1.0668 2.54 1.27 3.81 1.9304 5.08 2.54 6.4516 3.2512 1.27 0.635"
-WireBend=3
+WireBend=1
 WireBendSet=0
 WireCap=1
 MiterStyle=0
@@ -80,13 +80,13 @@ SwapLevel=0
 ArcDirection=0
 AddLevel=2
 PadsSameType=0
-Layer=47
+Layer=1
 
 [Win_2]
 Type="Schematic Editor"
 Number=2
 File="atkbldcdriver.sch"
-View="-500.418 -241.803 754.198 327.64"
+View="-199.977 -15.3886 91.806 117.046"
 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"
@@ -125,7 +125,7 @@ ArcDirection=0
 AddLevel=2
 PadsSameType=0
 Layer=91
-Views=" 1: -500.418 -241.803 754.198 327.64"
+Views=" 1: -199.977 -15.3886 91.806 117.046"
 Sheet="1"
 
 [Win_3]
diff --git a/embedded/README.md b/embedded/README.md
index 233a2fb..6c95c65 100644
--- a/embedded/README.md
+++ b/embedded/README.md
@@ -5,3 +5,8 @@ Firmware for the board follows the [automatakit](https://gitlab.cba.mit.edu/jake
 Communication is handled asynchronously: bytes received on the UART are loaded into a ringbuffer, where they are later parsed in to packets. Parsing happens as oven as possible. 
 
 Firmware for the xmega is under development, but you can see [firmware notes for the atsamd51 board](/embedded/atsamd51.md), and incidentally I've also done this with the [atsams70](/embedded/atsams70.md). Clearly, a few trips around the same yak. To shave. If you know what I mean.
+
+## Fast and Dirty 6-Step Timer-Based Commutation Mode
+
+To get spindles spinning with only a wee amount of c-programming time, I'm going to write a dirty/nasty/simple commutation scheme. 
+
diff --git a/embedded/atkbldcdriver/atkbldcdriver.atsln b/embedded/atkbldcdriver/atkbldcdriver.atsln
new file mode 100644
index 0000000..773b8e5
--- /dev/null
+++ b/embedded/atkbldcdriver/atkbldcdriver.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}") = "atkbldcdriver", "atkbldcdriver\atkbldcdriver.cproj", "{DCE6C7E3-EE26-4D79-826B-08594B9AD897}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|AVR = Debug|AVR
+		Release|AVR = Release|AVR
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{DCE6C7E3-EE26-4D79-826B-08594B9AD897}.Debug|AVR.ActiveCfg = Debug|AVR
+		{DCE6C7E3-EE26-4D79-826B-08594B9AD897}.Debug|AVR.Build.0 = Debug|AVR
+		{DCE6C7E3-EE26-4D79-826B-08594B9AD897}.Release|AVR.ActiveCfg = Release|AVR
+		{DCE6C7E3-EE26-4D79-826B-08594B9AD897}.Release|AVR.Build.0 = Release|AVR
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal
diff --git a/embedded/atkbldcdriver/atkbldcdriver/Debug/Makefile b/embedded/atkbldcdriver/atkbldcdriver/Debug/Makefile
new file mode 100644
index 0000000..55ad9d1
--- /dev/null
+++ b/embedded/atkbldcdriver/atkbldcdriver/Debug/Makefile
@@ -0,0 +1,185 @@
+################################################################################
+# 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 := 
+
+
+# Add inputs and outputs from these tool invocations to the build variables 
+C_SRCS +=  \
+../atkhandler.c \
+../atkport.c \
+../fastmath.c \
+../main.c \
+../pin.c \
+../ringbuffer.c \
+../spiport.c \
+../ams5047.c \
+../uartport.c
+
+
+PREPROCESSING_SRCS += 
+
+
+ASM_SRCS += 
+
+
+OBJS +=  \
+atkhandler.o \
+atkport.o \
+fastmath.o \
+main.o \
+pin.o \
+ringbuffer.o \
+spiport.o \
+ams5047.o \
+uartport.o
+
+OBJS_AS_ARGS +=  \
+atkhandler.o \
+atkport.o \
+fastmath.o \
+main.o \
+pin.o \
+ringbuffer.o \
+spiport.o \
+ams5047.o \
+uartport.o
+
+C_DEPS +=  \
+atkhandler.d \
+atkport.d \
+fastmath.d \
+main.d \
+pin.d \
+ringbuffer.d \
+spiport.d \
+ams5047.d \
+uartport.d
+
+C_DEPS_AS_ARGS +=  \
+atkhandler.d \
+atkport.d \
+fastmath.d \
+main.d \
+pin.d \
+ringbuffer.d \
+spiport.d \
+ams5047.d \
+uartport.d
+
+OUTPUT_FILE_PATH +=atkbldcdriver.elf
+
+OUTPUT_FILE_PATH_AS_ARGS +=atkbldcdriver.elf
+
+ADDITIONAL_DEPENDENCIES:=
+
+OUTPUT_FILE_DEP:= ./makedep.mk
+
+LIB_DEP+= 
+
+LINKER_SCRIPT_DEP+= 
+
+
+# AVR32/GNU C Compiler
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+./%.o: .././%.c
+	@echo Building file: $<
+	@echo Invoking: AVR/GNU C Compiler : 5.4.0
+	$(QUOTE)C:\Program Files (x86)\Atmel\Studio\7.0\toolchain\avr8\avr8-gnu-toolchain\bin\avr-gcc.exe$(QUOTE)  -x c -funsigned-char -funsigned-bitfields -DDEBUG  -I"C:\Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\XMEGAA_DFP\1.1.68\include"  -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -g2 -Wall -mmcu=atxmega256a3u -B "C:\Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\XMEGAA_DFP\1.1.68\gcc\dev\atxmega256a3u" -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: AVR/GNU Linker : 5.4.0
+	$(QUOTE)C:\Program Files (x86)\Atmel\Studio\7.0\toolchain\avr8\avr8-gnu-toolchain\bin\avr-gcc.exe$(QUOTE) -o$(OUTPUT_FILE_PATH_AS_ARGS) $(OBJS_AS_ARGS) $(USER_OBJS) $(LIBS) -Wl,-Map="atkbldcdriver.map" -Wl,--start-group -Wl,-lm  -Wl,--end-group -Wl,--gc-sections -mmcu=atxmega256a3u -B "C:\Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\XMEGAA_DFP\1.1.68\gcc\dev\atxmega256a3u"  
+	@echo Finished building target: $@
+	"C:\Program Files (x86)\Atmel\Studio\7.0\toolchain\avr8\avr8-gnu-toolchain\bin\avr-objcopy.exe" -O ihex -R .eeprom -R .fuse -R .lock -R .signature -R .user_signatures  "atkbldcdriver.elf" "atkbldcdriver.hex"
+	"C:\Program Files (x86)\Atmel\Studio\7.0\toolchain\avr8\avr8-gnu-toolchain\bin\avr-objcopy.exe" -j .eeprom  --set-section-flags=.eeprom=alloc,load --change-section-lma .eeprom=0  --no-change-warnings -O ihex "atkbldcdriver.elf" "atkbldcdriver.eep" || exit 0
+	"C:\Program Files (x86)\Atmel\Studio\7.0\toolchain\avr8\avr8-gnu-toolchain\bin\avr-objdump.exe" -h -S "atkbldcdriver.elf" > "atkbldcdriver.lss"
+	"C:\Program Files (x86)\Atmel\Studio\7.0\toolchain\avr8\avr8-gnu-toolchain\bin\avr-objcopy.exe" -O srec -R .eeprom -R .fuse -R .lock -R .signature -R .user_signatures "atkbldcdriver.elf" "atkbldcdriver.srec"
+	"C:\Program Files (x86)\Atmel\Studio\7.0\toolchain\avr8\avr8-gnu-toolchain\bin\avr-size.exe" "atkbldcdriver.elf"
+	
+	
+
+
+
+
+
+# Other Targets
+clean:
+	-$(RM) $(OBJS_AS_ARGS) $(EXECUTABLES)  
+	-$(RM) $(C_DEPS_AS_ARGS)   
+	rm -rf "atkbldcdriver.elf" "atkbldcdriver.a" "atkbldcdriver.hex" "atkbldcdriver.lss" "atkbldcdriver.eep" "atkbldcdriver.map" "atkbldcdriver.srec" "atkbldcdriver.usersignatures"
+	
\ No newline at end of file
diff --git a/embedded/atkbldcdriver/atkbldcdriver/Debug/atkbldcdriver.eep b/embedded/atkbldcdriver/atkbldcdriver/Debug/atkbldcdriver.eep
new file mode 100644
index 0000000..7c166a1
--- /dev/null
+++ b/embedded/atkbldcdriver/atkbldcdriver/Debug/atkbldcdriver.eep
@@ -0,0 +1 @@
+:00000001FF
diff --git a/embedded/atkbldcdriver/atkbldcdriver/Debug/makedep.mk b/embedded/atkbldcdriver/atkbldcdriver/Debug/makedep.mk
new file mode 100644
index 0000000..d5a1f4d
--- /dev/null
+++ b/embedded/atkbldcdriver/atkbldcdriver/Debug/makedep.mk
@@ -0,0 +1,22 @@
+################################################################################
+# Automatically-generated file. Do not edit or delete the file
+################################################################################
+
+atkhandler.c
+
+atkport.c
+
+fastmath.c
+
+main.c
+
+pin.c
+
+ringbuffer.c
+
+spiport.c
+
+ams5047.c
+
+uartport.c
+
diff --git a/embedded/atkbldcdriver/atkbldcdriver/ams5047.c b/embedded/atkbldcdriver/atkbldcdriver/ams5047.c
new file mode 100644
index 0000000..651c21b
--- /dev/null
+++ b/embedded/atkbldcdriver/atkbldcdriver/ams5047.c
@@ -0,0 +1,40 @@
+/*
+ * ams5047x.c
+ *
+ * Created: 2/7/2018 10:17:39 PM
+ *  Author: Jake
+ */ 
+
+#include "ams5047.h"
+
+void ams5047_init(ams5047_t *ams, spiport_t *spi, pin_t *en, pin_t *sg){	
+	ams->spi = spi;
+	ams->en_pin = en;
+	ams->sg_pin = sg;
+}
+
+void ams5047_write(ams5047_t *ams, uint32_t word){
+	// ?
+	uint8_t bytes[3];
+	bytes[0] = word >> 16;// | 0b11110000; // top 4 & mask for visibility
+	bytes[1] = word >> 8; // middle 8
+	bytes[2] = word; // last 4 and 0's
+	spi_txchars_polled(ams->spi, bytes, 3);
+}
+
+void ams5047_start(ams5047_t *ams){
+	//
+}
+
+void ams5047_update(ams5047_t *ams){
+	uint32_t smarten = 0b10100000000000000000;
+	ams5047_write(ams, smarten);
+}
+
+void ams5047_enable(ams5047_t *ams){
+	pin_clear(ams->en_pin);
+}
+
+void ams5047_disable(ams5047_t *ams){
+	pin_set(ams->en_pin);
+}
\ No newline at end of file
diff --git a/embedded/atkbldcdriver/atkbldcdriver/ams5047.h b/embedded/atkbldcdriver/atkbldcdriver/ams5047.h
new file mode 100644
index 0000000..3b560b2
--- /dev/null
+++ b/embedded/atkbldcdriver/atkbldcdriver/ams5047.h
@@ -0,0 +1,38 @@
+/*
+ * ams5047.h
+ *
+ * Created: 2/7/2018 10:17:49 PM
+ *  Author: Jake
+ */ 
+
+
+#ifndef AMS5047_H_
+#define AMS5047_H_
+
+#include "spiport.h"
+#include "pin.h"
+
+// TODO: adding updates (microstep, current)
+// in that, calculating current
+// TODO: reading stallguard, understanding if is already doing closed loop?
+
+typedef struct{
+	spiport_t *spi;
+	
+	pin_t *en_pin;
+	pin_t *sg_pin;
+}ams5047_t;
+
+void ams5047_init(ams5047_t *ams, spiport_t *spi, pin_t *en, pin_t *sg);
+
+void ams5047_write(ams5047_t *ams, uint32_t word);
+
+void ams5047_start(ams5047_t *ams);
+
+void ams5047_update(ams5047_t *ams);
+
+void ams5047_enable(ams5047_t *ams);
+
+void ams5047_disable(ams5047_t *ams);
+
+#endif /* AMS5047_H_ */
\ No newline at end of file
diff --git a/embedded/atkbldcdriver/atkbldcdriver/atkbldcdriver.componentinfo.xml b/embedded/atkbldcdriver/atkbldcdriver/atkbldcdriver.componentinfo.xml
new file mode 100644
index 0000000..4213287
--- /dev/null
+++ b/embedded/atkbldcdriver/atkbldcdriver/atkbldcdriver.componentinfo.xml
@@ -0,0 +1,86 @@
+<?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>Device</CClass>
+			<CGroup>Startup</CGroup>
+			<CSub></CSub>
+			<CVariant></CVariant>
+			<CVendor>Atmel</CVendor>
+			<CVersion>1.1.0</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\atmel\XMEGAA_DFP\1.1.68\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\XMEGAA_DFP\1.1.68\include\avr\iox256a3u.h</AbsolutePath>
+					<Attribute></Attribute>
+					<Category>header</Category>
+					<Condition>C</Condition>
+					<FileContentHash>Ogej+KWLQ2y+wOiUkMjAUg==</FileContentHash>
+					<FileVersion></FileVersion>
+					<Name>include/avr/iox256a3u.h</Name>
+					<SelectString></SelectString>
+					<SourcePath></SourcePath>
+				</d4p1:anyType>
+				<d4p1:anyType i:type="FileInfo">
+					<AbsolutePath>C:/Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\XMEGAA_DFP\1.1.68\templates\main.c</AbsolutePath>
+					<Attribute>template</Attribute>
+					<Category>source</Category>
+					<Condition>C Exe</Condition>
+					<FileContentHash>W0NBHkkZq5Rx0zexX2tYMw==</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\XMEGAA_DFP\1.1.68\templates\main.cpp</AbsolutePath>
+					<Attribute>template</Attribute>
+					<Category>source</Category>
+					<Condition>C Exe</Condition>
+					<FileContentHash>YXFphlh0CtZJU+ebktABgQ==</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\XMEGAA_DFP\1.1.68\gcc\dev\atxmega256a3u</AbsolutePath>
+					<Attribute></Attribute>
+					<Category>libraryPrefix</Category>
+					<Condition>GCC</Condition>
+					<FileContentHash i:nil="true" />
+					<FileVersion></FileVersion>
+					<Name>gcc/dev/atxmega256a3u</Name>
+					<SelectString></SelectString>
+					<SourcePath></SourcePath>
+				</d4p1:anyType>
+			</Files>
+			<PackName>XMEGAA_DFP</PackName>
+			<PackPath>C:/Program Files (x86)/Atmel/Studio/7.0/Packs/atmel/XMEGAA_DFP/1.1.68/Atmel.XMEGAA_DFP.pdsc</PackPath>
+			<PackVersion>1.1.68</PackVersion>
+			<PresentInProject>true</PresentInProject>
+			<ReferenceConditionId>ATxmega256A3U</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/atkbldcdriver/atkbldcdriver/atkbldcdriver.cproj b/embedded/atkbldcdriver/atkbldcdriver/atkbldcdriver.cproj
new file mode 100644
index 0000000..500ce0a
--- /dev/null
+++ b/embedded/atkbldcdriver/atkbldcdriver/atkbldcdriver.cproj
@@ -0,0 +1,195 @@
+<?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.AVRGCC8.C</ToolchainName>
+    <ProjectGuid>dce6c7e3-ee26-4d79-826b-08594b9ad897</ProjectGuid>
+    <avrdevice>ATxmega256A3U</avrdevice>
+    <avrdeviceseries>none</avrdeviceseries>
+    <OutputType>Executable</OutputType>
+    <Language>C</Language>
+    <OutputFileName>$(MSBuildProjectName)</OutputFileName>
+    <OutputFileExtension>.elf</OutputFileExtension>
+    <OutputDirectory>$(MSBuildProjectDirectory)\$(Configuration)</OutputDirectory>
+    <AssemblyName>atkbldcdriver</AssemblyName>
+    <Name>atkbldcdriver</Name>
+    <RootNamespace>atkbldcdriver</RootNamespace>
+    <ToolchainFlavour>Native</ToolchainFlavour>
+    <KeepTimersRunning>true</KeepTimersRunning>
+    <OverrideVtor>false</OverrideVtor>
+    <CacheFlash>true</CacheFlash>
+    <ProgFlashFromRam>true</ProgFlashFromRam>
+    <RamSnippetAddress>0x20000000</RamSnippetAddress>
+    <UncachedRange />
+    <preserveEEPROM>true</preserveEEPROM>
+    <OverrideVtorValue>exception_table</OverrideVtorValue>
+    <BootSegment>2</BootSegment>
+    <ResetRule>0</ResetRule>
+    <eraseonlaunchrule>0</eraseonlaunchrule>
+    <EraseKey />
+    <AsfFrameworkConfig>
+      <framework-data xmlns="">
+        <options />
+        <configurations />
+        <files />
+        <documentation help="" />
+        <offline-documentation help="" />
+        <dependencies>
+          <content-extension eid="atmel.asf" uuidref="Atmel.ASF" version="3.39.0" />
+        </dependencies>
+      </framework-data>
+    </AsfFrameworkConfig>
+    <avrtool>com.atmel.avrdbg.tool.atmelice</avrtool>
+    <avrtoolserialnumber>J41800087098</avrtoolserialnumber>
+    <avrdeviceexpectedsignature>0x1E9842</avrdeviceexpectedsignature>
+    <com_atmel_avrdbg_tool_atmelice>
+      <ToolOptions>
+        <InterfaceProperties>
+          <PdiClock>4000000</PdiClock>
+        </InterfaceProperties>
+        <InterfaceName>PDI</InterfaceName>
+      </ToolOptions>
+      <ToolType>com.atmel.avrdbg.tool.atmelice</ToolType>
+      <ToolNumber>J41800087098</ToolNumber>
+      <ToolName>Atmel-ICE</ToolName>
+    </com_atmel_avrdbg_tool_atmelice>
+    <avrtoolinterface>PDI</avrtoolinterface>
+    <avrtoolinterfaceclock>4000000</avrtoolinterfaceclock>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
+    <ToolchainSettings>
+      <AvrGcc>
+        <avrgcc.common.Device>-mmcu=atxmega256a3u -B "%24(PackRepoDir)\atmel\XMEGAA_DFP\1.1.68\gcc\dev\atxmega256a3u"</avrgcc.common.Device>
+        <avrgcc.common.outputfiles.hex>True</avrgcc.common.outputfiles.hex>
+        <avrgcc.common.outputfiles.lss>True</avrgcc.common.outputfiles.lss>
+        <avrgcc.common.outputfiles.eep>True</avrgcc.common.outputfiles.eep>
+        <avrgcc.common.outputfiles.srec>True</avrgcc.common.outputfiles.srec>
+        <avrgcc.common.outputfiles.usersignatures>False</avrgcc.common.outputfiles.usersignatures>
+        <avrgcc.compiler.general.ChangeDefaultCharTypeUnsigned>True</avrgcc.compiler.general.ChangeDefaultCharTypeUnsigned>
+        <avrgcc.compiler.general.ChangeDefaultBitFieldUnsigned>True</avrgcc.compiler.general.ChangeDefaultBitFieldUnsigned>
+        <avrgcc.compiler.symbols.DefSymbols>
+          <ListValues>
+            <Value>NDEBUG</Value>
+          </ListValues>
+        </avrgcc.compiler.symbols.DefSymbols>
+        <avrgcc.compiler.directories.IncludePaths>
+          <ListValues>
+            <Value>%24(PackRepoDir)\atmel\XMEGAA_DFP\1.1.68\include</Value>
+          </ListValues>
+        </avrgcc.compiler.directories.IncludePaths>
+        <avrgcc.compiler.optimization.level>Optimize for size (-Os)</avrgcc.compiler.optimization.level>
+        <avrgcc.compiler.optimization.PackStructureMembers>True</avrgcc.compiler.optimization.PackStructureMembers>
+        <avrgcc.compiler.optimization.AllocateBytesNeededForEnum>True</avrgcc.compiler.optimization.AllocateBytesNeededForEnum>
+        <avrgcc.compiler.warnings.AllWarnings>True</avrgcc.compiler.warnings.AllWarnings>
+        <avrgcc.linker.libraries.Libraries>
+          <ListValues>
+            <Value>libm</Value>
+          </ListValues>
+        </avrgcc.linker.libraries.Libraries>
+        <avrgcc.assembler.general.IncludePaths>
+          <ListValues>
+            <Value>%24(PackRepoDir)\atmel\XMEGAA_DFP\1.1.68\include</Value>
+          </ListValues>
+        </avrgcc.assembler.general.IncludePaths>
+      </AvrGcc>
+    </ToolchainSettings>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
+    <ToolchainSettings>
+      <AvrGcc>
+        <avrgcc.common.Device>-mmcu=atxmega256a3u -B "%24(PackRepoDir)\atmel\XMEGAA_DFP\1.1.68\gcc\dev\atxmega256a3u"</avrgcc.common.Device>
+        <avrgcc.common.outputfiles.hex>True</avrgcc.common.outputfiles.hex>
+        <avrgcc.common.outputfiles.lss>True</avrgcc.common.outputfiles.lss>
+        <avrgcc.common.outputfiles.eep>True</avrgcc.common.outputfiles.eep>
+        <avrgcc.common.outputfiles.srec>True</avrgcc.common.outputfiles.srec>
+        <avrgcc.common.outputfiles.usersignatures>False</avrgcc.common.outputfiles.usersignatures>
+        <avrgcc.compiler.general.ChangeDefaultCharTypeUnsigned>True</avrgcc.compiler.general.ChangeDefaultCharTypeUnsigned>
+        <avrgcc.compiler.general.ChangeDefaultBitFieldUnsigned>True</avrgcc.compiler.general.ChangeDefaultBitFieldUnsigned>
+        <avrgcc.compiler.symbols.DefSymbols>
+          <ListValues>
+            <Value>DEBUG</Value>
+          </ListValues>
+        </avrgcc.compiler.symbols.DefSymbols>
+        <avrgcc.compiler.directories.IncludePaths>
+          <ListValues>
+            <Value>%24(PackRepoDir)\atmel\XMEGAA_DFP\1.1.68\include</Value>
+          </ListValues>
+        </avrgcc.compiler.directories.IncludePaths>
+        <avrgcc.compiler.optimization.level>Optimize (-O1)</avrgcc.compiler.optimization.level>
+        <avrgcc.compiler.optimization.PackStructureMembers>True</avrgcc.compiler.optimization.PackStructureMembers>
+        <avrgcc.compiler.optimization.AllocateBytesNeededForEnum>True</avrgcc.compiler.optimization.AllocateBytesNeededForEnum>
+        <avrgcc.compiler.optimization.DebugLevel>Default (-g2)</avrgcc.compiler.optimization.DebugLevel>
+        <avrgcc.compiler.warnings.AllWarnings>True</avrgcc.compiler.warnings.AllWarnings>
+        <avrgcc.linker.libraries.Libraries>
+          <ListValues>
+            <Value>libm</Value>
+          </ListValues>
+        </avrgcc.linker.libraries.Libraries>
+        <avrgcc.assembler.general.IncludePaths>
+          <ListValues>
+            <Value>%24(PackRepoDir)\atmel\XMEGAA_DFP\1.1.68\include</Value>
+          </ListValues>
+        </avrgcc.assembler.general.IncludePaths>
+        <avrgcc.assembler.debugging.DebugLevel>Default (-Wa,-g)</avrgcc.assembler.debugging.DebugLevel>
+      </AvrGcc>
+    </ToolchainSettings>
+  </PropertyGroup>
+  <ItemGroup>
+    <Compile Include="atkhandler.c">
+      <SubType>compile</SubType>
+    </Compile>
+    <Compile Include="atkhandler.h">
+      <SubType>compile</SubType>
+    </Compile>
+    <Compile Include="atkport.c">
+      <SubType>compile</SubType>
+    </Compile>
+    <Compile Include="atkport.h">
+      <SubType>compile</SubType>
+    </Compile>
+    <Compile Include="fastmath.c">
+      <SubType>compile</SubType>
+    </Compile>
+    <Compile Include="fastmath.h">
+      <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="ams5047.c">
+      <SubType>compile</SubType>
+    </Compile>
+    <Compile Include="ams5047.h">
+      <SubType>compile</SubType>
+    </Compile>
+    <Compile Include="uartport.c">
+      <SubType>compile</SubType>
+    </Compile>
+    <Compile Include="uartport.h">
+      <SubType>compile</SubType>
+    </Compile>
+  </ItemGroup>
+  <Import Project="$(AVRSTUDIO_EXE_PATH)\\Vs\\Compiler.targets" />
+</Project>
\ No newline at end of file
diff --git a/embedded/atkbldcdriver/atkbldcdriver/atkhandler.c b/embedded/atkbldcdriver/atkbldcdriver/atkhandler.c
new file mode 100644
index 0000000..d930ce5
--- /dev/null
+++ b/embedded/atkbldcdriver/atkbldcdriver/atkhandler.c
@@ -0,0 +1,164 @@
+/*
+* atkhandler.c
+*
+* Created: 3/12/2018 11:55:30 AM
+*  Author: Jake
+*/
+
+#include "hardware.h"
+#include "atkhandler.h"
+
+int32_t steps;
+
+void atk_handle_packet(uint8_t *packet, uint8_t length){
+	// dirty debug reply
+	//atk_return_packet(packet, length);
+	// through packet
+	int i = 0;
+	int atk_handler_state = ATK_HANDLER_OUTSIDE;
+	uint8_t testReply[4] = {127, 12, 24, 48};
+		
+	while(i < length){ // prep for the messy double switch :|
+		switch (atk_handler_state){
+			case ATK_HANDLER_OUTSIDE:
+				if (packet[i] == ATK_END_ROUTE_DELIMITER){
+					atk_handler_state = ATK_HANDLER_INSIDE;
+				} 
+				i ++;
+				break;
+			
+			case ATK_HANDLER_INSIDE:
+				switch (packet[i]){
+					case DELIM_KEY_TEST:
+						pin_toggle(&stlerr);
+						// see the packet, make sure you're not doing something else with this light
+						atk_reply_packet(packet, testReply, 4);
+						i ++;
+						break;
+					
+					case DELIM_KEY_RESET:
+						CCP = CCP_IOREG_gc;
+						RST.CTRL = RST_SWRST_bm;
+						break;
+					
+					case DELIM_KEY_ENABLE:
+						
+						break;
+					
+					case DELIM_KEY_DISABLE:
+					
+						break;
+						
+					case DELIM_KEY_SPEED:
+						// set timers
+						break;
+					
+					case DELIM_KEY_TRAPEZOID:
+						//pin_toggle(&stlerr);
+						if(i + 12 > length){
+							i ++;
+						} else {
+							// stepper trapezoid block
+							i += 21;
+						}
+						break;
+					
+					case DELIM_KEY_WAIT:
+						if(i + 8 > length){
+							i ++;
+						} else {
+							// stepper wait block
+							i += 8;
+						}
+						break;
+											
+					default:
+						// probably an error
+						i ++;
+						break;
+				} // end interior switch
+			break;
+			
+			default :
+			// throw err
+			break;
+		} // end y/n switch
+	}
+}
+
+// HERE return with address header, or from old packet with new data
+
+uint8_t ackPack[256];
+
+void atk_reply_packet(uint8_t *opPacket, uint8_t *replyData, uint8_t replyLength){
+	// find address chunk in opPacket
+	int i = 2;
+	int stop = 0;
+	while(i < opPacket[0]){
+		if(opPacket[i] == ATK_END_ROUTE_DELIMITER){
+			stop = i;
+			break;
+		}
+		i ++;
+	}
+	
+	uint8_t ackLength = stop + replyLength + 1;
+	ackPack[0] = ackLength;
+	
+	if(stop){
+		// reverse the address header
+		for(int a = stop - 1, b = 1; a >= 1; a--, b++){
+			ackPack[b] = opPacket[a];
+		}
+		// and append the end block
+		ackPack[stop] = ATK_END_ROUTE_DELIMITER;
+		// now fill with provided reply data
+		for(int u = 0; u <= replyLength; u ++){
+			ackPack[u + stop + 1] = replyData[u];
+		}
+		// checking the port exists, send it out
+		if(ackPack[1] >= SYSTEM_NUM_UPS){
+			ackPack[1] = SYSTEM_NUM_UPS - 1;
+		}
+		uart_sendchars_buffered(ups[ackPack[1]], ackPack, ackPack[0]);//ups[ackPack[1]], ackPack, ackLength);
+	}
+}
+
+void atk_return_packet(uint8_t *packet, uint8_t length){
+	//uart_sendchar_buffered(ups[1], 120);
+	//uart_sendchars_buffered(ups[1], packet, length);
+	// using this placeholder 
+	ackPack[0] = length;
+	// find route header
+	int i = 2;
+	int stop = 0;
+	while(i < length){
+		if(packet[i] == ATK_END_ROUTE_DELIMITER){
+			stop = i;
+			break;
+		}
+		i ++;
+	}
+	// do the business
+	if(stop){
+		// reverse the address header
+		for(int a = stop - 1, b = 1; a >= 1; a--, b++){
+			ackPack[b] = packet[a];
+		}
+		// fill the rest with same packet data
+		ackPack[stop] = ATK_END_ROUTE_DELIMITER;
+		for(int u = stop; u < length; u ++){
+			ackPack[u] = packet[u];
+		}
+		// checking the packet exists, send it out
+		if(ackPack[1] >= SYSTEM_NUM_UPS){
+			ackPack[1] = SYSTEM_NUM_UPS - 1;
+		}
+		uart_sendchars_buffered(ups[ackPack[1]], ackPack, ackPack[0]);
+		// NOW:
+		// looking for justice: why no return packet on double length hop?
+		// debug with 2nd ftdi
+		//uart_sendchar_buffered(ups[1], 121);
+		//uart_sendchars_buffered(ups[1], ackpack, length);
+	}
+}
\ No newline at end of file
diff --git a/embedded/atkbldcdriver/atkbldcdriver/atkhandler.h b/embedded/atkbldcdriver/atkbldcdriver/atkhandler.h
new file mode 100644
index 0000000..a761690
--- /dev/null
+++ b/embedded/atkbldcdriver/atkbldcdriver/atkhandler.h
@@ -0,0 +1,32 @@
+/*
+ * atkhandler.h
+ *
+ * Created: 3/12/2018 11:55:40 AM
+ *  Author: Jake
+ */ 
+
+
+#ifndef ATKHANDLER_H_
+#define ATKHANDLER_H_
+
+#include <avr/io.h>
+
+#define ATK_HANDLER_OUTSIDE 0
+#define ATK_HANDLER_INSIDE 1
+
+#define DELIM_KEY_TEST 127 // toggles a light, to test network
+#define DELIM_KEY_RESET 128 
+
+#define DELIM_KEY_TRAPEZOID 131 
+#define DELIM_KEY_WAIT 132
+
+#define DELIM_KEY_SPEED 141
+#define DELIM_KEY_ENABLE 142
+#define DELIM_KEY_DISABLE 143
+
+void atk_handle_packet(uint8_t *packet, uint8_t length);
+
+void atk_reply_packet(uint8_t *opPacket, uint8_t *replyData, uint8_t replyLength);
+void atk_return_packet(uint8_t *packet, uint8_t length);
+
+#endif /* atkHANDLER_H_ */
\ No newline at end of file
diff --git a/embedded/atkbldcdriver/atkbldcdriver/atkport.c b/embedded/atkbldcdriver/atkbldcdriver/atkport.c
new file mode 100644
index 0000000..65b80e0
--- /dev/null
+++ b/embedded/atkbldcdriver/atkbldcdriver/atkport.c
@@ -0,0 +1,123 @@
+/*
+ * atkport.c
+ *
+ * Created: 2/23/2018 9:17:48 AM
+ *  Author: Jake
+ */ 
+
+#include "atkport.h"
+#include "hardware.h"
+#include "fastmath.h"
+
+void atkport_init(atkport_t *atkp, uint8_t portnum, uartport_t *uart){
+	atkp->uart = uart;
+	atkp->portnum = portnum;
+	
+	atkport_reset(atkp);
+}
+
+void atkport_reset(atkport_t *atkp){
+	atkp->packet_num = 0;
+	atkp->packets_ready = 0;
+	atkp->packet_state = ATKPORT_OUTSIDE_PACKET;
+	atkp->packet_position = 0;
+	
+	pin_set(atkp->uart->stlrx);
+	pin_set(atkp->uart->stltx);
+}
+
+void atkport_scan(atkport_t *atkp, uint32_t maxpackets){
+	// scan through for completely received packets
+	while(atkp->packets_ready <= maxpackets){
+		// check that we have bytes to read out of the buffer
+		if(atkp->uart->rbrx->head == atkp->uart->rbrx->tail){ // direct access, rather than through rbempty() shaves 2us
+			pin_set(atkp->uart->stlrx);
+			break;
+		} else {
+			// pull bytes out of buffer into the packet structure
+			atkp->packets[atkp->packet_num][atkp->packet_position] = rb_get(atkp->uart->rbrx);
+			atkp->packet_position ++;
+			// now segment, point to them
+			if(atkp->packet_position >= atkp->packets[atkp->packet_num][0]){
+				// length is 1st byte, like array[n] not array[n-1]
+				// now volley for next pass
+				// packet_num is index of head of packet buffer (just an array)
+				atkp->packet_num = fastModulo((atkp->packet_num + 1), ATKPORT_NUM_STATIC_PACKETS); // inc. and loop
+				// packets_ready is the number of ready-state packets in that buffer (array)
+				atkp->packets_ready ++;
+				// the position, in bytes, where we are currently operating.
+				// at this point, we have come to the end, so we're resetting counter for the next
+				atkp->packet_position = 0;
+			}
+		}
+	} 
+	// end 1st scan for packets, now we know we have atkport->packet_num packets completely received
+	// now we handle those packets	
+	while(atkp->packets_ready > 0){
+		// the particular packet index
+		uint32_t p = fastModulo((atkp->packet_num + ATKPORT_NUM_STATIC_PACKETS - atkp->packets_ready), ATKPORT_NUM_STATIC_PACKETS); //(atkp->packet_num + ATKPORT_NUM_STATIC_PACKETS - atkp->packets_ready) % ATKPORT_NUM_STATIC_PACKETS;
+		// first we shift the old pointer out (p[1] is, at the moment, the port the last node tx'd on)
+		atkpacket_shift_pointer(atkp->packets[p], atkp->portnum);
+		// now p[1] is next port
+		// now to handle
+		// [p][0] is length of packet
+		if(atkp->packets[p][1] == ATK_ROUTE_POINTER){
+			atk_handle_packet(atkp->packets[p], atkp->packets[p][0]);
+		} else if(atkp->packets[p][1] == ATK_ROUTE_FLOOD){
+			// loop through bytes to find pointer and increment
+			// now ship it out on all ports
+			for(int i = 0; i < ATKPORT_NUM_PORTS; i ++){
+				if(i == atkp->portnum){
+					// don't flood back
+				} else {
+					uart_sendchars_buffered(ups[i], atkp->packets[p], atkp->packets[p][0]);
+				}
+			}
+		} else {
+			// packet is for a particular port,
+			if(atkp->packets[p][1] > ATKPORT_NUM_PORTS){
+				// port does not exist, throw error
+				// pin_clear(&stlerr);
+			} else {
+				// debug option
+				//uart_sendchars_buffered(&upU, atkp->packets[p], atkp->packets[p][0]);
+				uart_sendchars_buffered(ups[atkp->packets[p][1]], atkp->packets[p], atkp->packets[p][0]);
+			}
+		}
+		// debug reply (at the moment, reply is handled in atk_handle_packet
+		// uart_sendchars_buffered(atkp->uart, atkp->packets[p], atkp->packets[p][0]);
+		atkp->packets_ready --;
+	}
+}
+
+void atkpacket_shift_pointer(uint8_t *packet, uint8_t portnum){
+	int i = 2;
+	while(i < packet[0]){ // while less than length
+		if(packet[i] == ATK_END_ROUTE_DELIMITER){
+			// put our port in tail
+			packet[i-1] = portnum;
+			break;
+		} else {
+			// shift 'em down
+			packet[i-1] = packet[i];
+		}
+		i ++;
+	}
+}
+
+void atkport_send_packet(uint8_t *address, uint8_t address_length, uint8_t *payload, uint8_t payloadlength){
+	// 1st byte is port out
+	// not yet implemented, using atk_return_packet ... all of these could be cleaner
+}
+
+// UNIT TESTS:
+/*
+ flood packets
+ multiple receptions? handle in app?
+ packets no end addr bar delimiter, packets no pointer, general white noise
+ packets varying length
+ packets wrong length ? very hard to catch w/o hella state ... timeout?
+	packets no end addr delimiter?
+ packets to ports not existing
+ // next: write javascript terminal packet builder for unit tests!
+*/
\ No newline at end of file
diff --git a/embedded/atkbldcdriver/atkbldcdriver/atkport.h b/embedded/atkbldcdriver/atkbldcdriver/atkport.h
new file mode 100644
index 0000000..c99365f
--- /dev/null
+++ b/embedded/atkbldcdriver/atkbldcdriver/atkport.h
@@ -0,0 +1,47 @@
+/*
+ * atkport.h
+ *
+ * Created: 2/23/2018 9:17:34 AM
+ *  Author: Jake
+ */ 
+
+
+#ifndef ATKPORT_H_
+#define ATKPORT_H_
+
+#include "uartport.h"
+#include "pin.h"
+
+#define ATKPORT_NUM_STATIC_PACKETS 8
+#define ATKPORT_NUM_PORTS 6
+
+#define ATKPORT_OUTSIDE_PACKET 0
+#define ATKPORT_INSIDE_PACKET 1
+
+#define ATK_END_ROUTE_DELIMITER 255
+#define ATK_ROUTE_POINTER 254
+#define ATK_ROUTE_FLOOD 253
+
+typedef struct{
+	uartport_t *uart;
+	
+	uint8_t portnum; // which port are we
+	
+	uint32_t packet_num;
+	uint32_t packet_position;
+	uint32_t packets_ready;
+	uint32_t packet_state;
+	uint8_t packets[ATKPORT_NUM_STATIC_PACKETS][256]; // packets for handling by app
+}atkport_t;
+
+void atkport_init(atkport_t *atkp, uint8_t portnum, uartport_t *uart);
+
+void atkport_reset(atkport_t *atkp);
+
+void atkport_scan(atkport_t *atkp, uint32_t maxpackets);
+
+void atkpacket_shift_pointer(uint8_t *packet, uint8_t portnum);
+
+void atkport_send_packet(uint8_t *address, uint8_t address_length, uint8_t *payload, uint8_t payloadlength);
+
+#endif /* atkPORT_H_ */
\ No newline at end of file
diff --git a/embedded/atkbldcdriver/atkbldcdriver/fastmath.c b/embedded/atkbldcdriver/atkbldcdriver/fastmath.c
new file mode 100644
index 0000000..91d749c
--- /dev/null
+++ b/embedded/atkbldcdriver/atkbldcdriver/fastmath.c
@@ -0,0 +1,11 @@
+/*
+ * fastmath.c
+ *
+ * Created: 6/20/2018 12:38:38 PM
+ *  Author: Jake
+ */ 
+
+int fastModulo(int dividend, int divisor){
+	// divisor must be a power of 2!
+	return dividend & (divisor - 1);
+}
\ No newline at end of file
diff --git a/embedded/atkbldcdriver/atkbldcdriver/fastmath.h b/embedded/atkbldcdriver/atkbldcdriver/fastmath.h
new file mode 100644
index 0000000..d1c2cb1
--- /dev/null
+++ b/embedded/atkbldcdriver/atkbldcdriver/fastmath.h
@@ -0,0 +1,14 @@
+/*
+ * fastmath.h
+ *
+ * Created: 6/20/2018 12:35:50 PM
+ *  Author: Jake
+ */ 
+
+
+#ifndef FASTMATH_H_
+#define FASTMATH_H_
+
+int fastModulo(int dividend, int divisor);
+
+#endif /* FASTMATH_H_ */
\ No newline at end of file
diff --git a/embedded/atkbldcdriver/atkbldcdriver/hardware.h b/embedded/atkbldcdriver/atkbldcdriver/hardware.h
new file mode 100644
index 0000000..03524c4
--- /dev/null
+++ b/embedded/atkbldcdriver/atkbldcdriver/hardware.h
@@ -0,0 +1,68 @@
+/*
+ * hardware.h
+ *
+ * Created: 6/18/2018 12:18:05 PM
+ *  Author: Jake
+ */ 
+
+
+#ifndef HARDWARE_H_
+#define HARDWARE_H_
+
+#include "pin.h"
+#include "ringbuffer.h"
+#include "uartport.h"
+#include "spiport.h"
+#include "atkport.h"
+#include "atkhandler.h"
+#include "ams5047.h"
+
+// results in 1MBaud
+#define SYSTEM_BAUDA 3
+#define SYSTEM_BAUDB 0
+#define SYSTEM_NUM_UPS 1
+
+pin_t stlclk;
+pin_t stlerr;
+
+// UP0
+
+ringbuffer_t up0rbrx;
+ringbuffer_t up0rbtx;
+
+uartport_t up0;
+
+pin_t up0rxled;
+pin_t up0txled;
+
+atkport_t atkp0;
+
+// UPS
+
+uartport_t *ups[SYSTEM_NUM_UPS];
+
+// Hardware
+// SPI
+
+spiport_t spiEncoder;
+pin_t spiEncCsPin;
+
+ams5047_t ams5047;
+
+// DRV8302 Business
+
+pin_t drvEnPin;
+pin_t drvModePwm;
+pin_t drvModeGain;
+pin_t drvDcCal;
+
+pin_t drvFault;
+pin_t drvOCTW;
+
+// controller functions 
+
+// bldc_t bldc;
+
+unsigned long timebase;
+
+#endif /* HARDWARE_H_ */
\ No newline at end of file
diff --git a/embedded/atkbldcdriver/atkbldcdriver/main.c b/embedded/atkbldcdriver/atkbldcdriver/main.c
new file mode 100644
index 0000000..9966907
--- /dev/null
+++ b/embedded/atkbldcdriver/atkbldcdriver/main.c
@@ -0,0 +1,130 @@
+/*
+* atkrouter.c
+*
+* Created: 6/17/2018 2:48:08 PM
+* Author : Jake
+*/
+
+#include <avr/io.h>
+#include <avr/interrupt.h>
+#include "hardware.h"
+#include "fastmath.h"
+
+// first setup all the pins
+// want six step commutation, or sinpwm on encoder reading? 
+
+void clock_init(void){
+	OSC.XOSCCTRL = OSC_XOSCSEL_XTAL_256CLK_gc | OSC_FRQRANGE_12TO16_gc; // select external source
+	OSC.CTRL = OSC_XOSCEN_bm; // enable external source
+	while(!(OSC.STATUS & OSC_XOSCRDY_bm)); // wait for external
+	OSC.PLLCTRL = OSC_PLLSRC_XOSC_gc | OSC_PLLFAC0_bm | OSC_PLLFAC1_bm; // select external osc for pll, do pll = source * 3
+	//OSC.PLLCTRL = OSC_PLLSRC_XOSC_gc | OSC_PLLFAC1_bm; // pll = source * 2 for 32MHz std clock
+	OSC.CTRL |= OSC_PLLEN_bm; // enable PLL
+	while (!(OSC.STATUS & OSC_PLLRDY_bm)); // wait for PLL to be ready
+	CCP = CCP_IOREG_gc; // enable protected register change
+	CLK.CTRL = CLK_SCLKSEL_PLL_gc; // switch to PLL for main clock
+}
+
+void uarts_init(void){
+	// UP0
+	rb_init(&up0rbrx);
+	rb_init(&up0rbtx);
+	pin_init(&up0rxled, &PORTE, PIN4_bm, 4, 1);
+	pin_init(&up0txled, &PORTE, PIN5_bm, 5, 1);
+	uart_init(&up0, &USARTE1, &PORTE, PIN6_bm, PIN7_bm, &up0rbrx, &up0rbtx, &up0rxled, &up0txled);
+	//PORTE.PIN7CTRL = PORT_SRLEN_bm;
+	uart_start(&up0, SYSTEM_BAUDA, SYSTEM_BAUDB);
+	
+	ups[0] = &up0;
+}
+
+void atkps_init(void){
+	atkport_init(&atkp0, 0, &up0);
+}
+
+void encoder_init(void){
+	pin_init(&spiEncCsPin, &PORTD, PIN4_bm, 4, 1);
+	spi_init(&spiEncoder, &USARTD1, &PORTD, PIN6_bm, PIN7_bm, PIN5_bm, &spiEncCsPin);
+	spi_start(&spiEncoder, 0);
+}
+
+void drv_init(void){
+	
+}
+
+void pwm_init(void){
+	// 
+}
+
+void tickers_init(void){
+	// one 'ticker' to execute steps
+	// turn on TCC0, do perclk / 8
+	TCC0.CTRLA = TC_CLKSEL_DIV256_gc;
+	
+	// compare and capture at value
+	uint16_t pera = 40; // ~ 200us timer to start... 
+	// write low first, bc bussing / xmega 8-bit oddities cc datasheet @ 3.11
+	uint8_t peral = (uint8_t) pera;
+	uint8_t perah = (uint8_t) (pera >> 8);
+	TCC0.PERBUFL = peral;
+	TCC0.PERBUFH = perah;
+	
+	// set cca interrupt on
+	TCC0.INTCTRLA = TC_OVFINTLVL_HI_gc;
+		
+	// another ticker to execute accel
+	TCC1.CTRLA = TC_CLKSEL_DIV256_gc;
+	TCC1.PERBUFL = peral;
+	TCC1.PERBUFH = perah;
+	
+	TCC1.INTCTRLA = TC_OVFINTLVL_HI_gc;
+}
+
+int main(void)
+{
+	clock_init();
+	uarts_init();
+	atkps_init();
+	
+	// enable interrupts
+	sei();
+	PMIC.CTRL |= PMIC_LOLVLEN_bm | PMIC_MEDLVLEN_bm | PMIC_HILVLEN_bm;
+
+	pin_init(&stlclk, &PORTE, PIN1_bm, 1, 1);
+	pin_init(&stlerr, &PORTE, PIN0_bm, 0, 1);
+	pin_set(&stlerr);
+	pin_set(&stlclk);
+	
+	tickers_init();
+
+	// runtime globals
+	uint32_t tck = 0;
+
+	while (1)
+	{
+		atkport_scan(&atkp0, 2);
+		// just... as fast as we can 
+ 		tck++;
+ 		// this modulo op is slow AF
+ 		// that means streamlining atkport_scan without modulos is probably a rad thing
+    	if(!(fastModulo(tck, 4096))){
+     		pin_toggle(&stlclk);
+     	}
+	}
+}
+
+ISR(TCC0_OVF_vect){
+	//stepper_updatesteps(&stepper);
+}
+
+ISR(TCC1_OVF_vect){
+	//stepper_updateaccel(&stepper);
+}
+
+ISR(USARTE1_RXC_vect){
+	uart_rxhandler(&up0);
+}
+
+ISR(USARTE1_DRE_vect){
+	uart_txhandler(&up0);
+}
\ No newline at end of file
diff --git a/embedded/atkbldcdriver/atkbldcdriver/pin.c b/embedded/atkbldcdriver/atkbldcdriver/pin.c
new file mode 100644
index 0000000..071e771
--- /dev/null
+++ b/embedded/atkbldcdriver/atkbldcdriver/pin.c
@@ -0,0 +1,49 @@
+/*
+ * pin.c
+ *
+ * Created: 6/18/2018 12:22:50 PM
+ *  Author: Jake
+ */ 
+
+#include "pin.h"
+
+void pin_init(pin_t *pin, PORT_t *port, uint8_t pin_bm, uint8_t pin_pos, uint8_t inout){
+	pin->port = port;
+	pin->pin_bm = pin_bm;
+	pin->pin_pos = pin_pos;
+	if(inout){
+		pin_output(pin);
+	} else {
+		pin_input(pin);
+	}
+}
+
+void pin_output(pin_t *pin){
+	pin->port->DIRSET = pin->pin_bm;
+}
+
+void pin_set(pin_t *pin){
+	pin->port->OUTSET = pin->pin_bm;
+}
+void pin_clear(pin_t *pin){
+	pin->port->OUTCLR = pin->pin_bm;
+}
+
+void pin_toggle(pin_t *pin){
+	pin->port->OUTTGL = pin->pin_bm;
+}
+
+void pin_input(pin_t *pin){
+	pin->port->DIRCLR = pin->pin_bm;
+}
+
+void pin_pullup(pin_t *pin){
+	// ? how to access PIN0CTRL, etc?
+}
+void pin_pulldown(pin_t *pin){
+	// 
+}
+
+uint8_t pin_read(pin_t *pin){
+	return (pin->port->IN & pin->pin_bm);
+}
\ No newline at end of file
diff --git a/embedded/atkbldcdriver/atkbldcdriver/pin.h b/embedded/atkbldcdriver/atkbldcdriver/pin.h
new file mode 100644
index 0000000..d7ddab6
--- /dev/null
+++ b/embedded/atkbldcdriver/atkbldcdriver/pin.h
@@ -0,0 +1,34 @@
+/*
+ * pin.h
+ *
+ * Created: 6/18/2018 12:22:58 PM
+ *  Author: Jake
+ */ 
+
+
+#ifndef PIN_H_
+#define PIN_H_
+
+#include "avr/io.h"
+
+typedef struct {
+	PORT_t *port;
+	uint8_t pin_bm;
+	uint8_t pin_pos;
+}pin_t;
+
+void pin_init(pin_t *pin, PORT_t *port, uint8_t pin_bm, uint8_t pin_pos, uint8_t inout);
+
+void pin_output(pin_t *pin);
+void pin_set(pin_t *pin);
+void pin_clear(pin_t *pin);
+void pin_toggle(pin_t *pin);
+
+void pin_input(pin_t *pin);
+void pin_pullup(pin_t *pin);
+void pin_pulldown(pin_t *pin);
+
+uint8_t pin_read(pin_t *pin);
+
+
+#endif /* PIN_H_ */
\ No newline at end of file
diff --git a/embedded/atkbldcdriver/atkbldcdriver/ringbuffer.c b/embedded/atkbldcdriver/atkbldcdriver/ringbuffer.c
new file mode 100644
index 0000000..a77dc50
--- /dev/null
+++ b/embedded/atkbldcdriver/atkbldcdriver/ringbuffer.c
@@ -0,0 +1,72 @@
+/*
+ * ringbuffer.c
+ *
+ * Created: 2/7/2018 11:39:44 AM
+ *  Author: Jake
+ */ 
+
+#include "ringbuffer.h"
+#include "fastmath.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 fastModulo((rb->head + 1), RINGBUFFER_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 = fastModulo((rb->head + 1), RINGBUFFER_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 = fastModulo((rb->tail + 1), RINGBUFFER_SIZE);
+	return data;
+}
+
diff --git a/embedded/atkbldcdriver/atkbldcdriver/ringbuffer.h b/embedded/atkbldcdriver/atkbldcdriver/ringbuffer.h
new file mode 100644
index 0000000..921c8ba
--- /dev/null
+++ b/embedded/atkbldcdriver/atkbldcdriver/ringbuffer.h
@@ -0,0 +1,43 @@
+/*
+ * 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 "avr/io.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/atkbldcdriver/atkbldcdriver/spiport.c b/embedded/atkbldcdriver/atkbldcdriver/spiport.c
new file mode 100644
index 0000000..a7698bc
--- /dev/null
+++ b/embedded/atkbldcdriver/atkbldcdriver/spiport.c
@@ -0,0 +1,54 @@
+/*
+ * spiport.c
+ *
+ * Created: 2/7/2018 10:51:42 AM
+ *  Author: Jake
+ */ 
+
+#include "spiport.h"
+
+void spi_init(spiport_t *spi, USART_t *com, PORT_t *port, uint8_t miso_bm, uint8_t mosi_bm, uint8_t sck_bm, pin_t *csn){
+	spi->com = com;
+	spi->port = port;
+	
+	spi->miso_bm = miso_bm;
+	spi->mosi_bm = mosi_bm;
+	spi->sck_bm = sck_bm;
+	spi->csn = csn;
+}
+
+void spi_start(spiport_t *spi, uint8_t cpha){
+	spi->port->DIRSET = spi->mosi_bm;
+	spi->port->DIRSET = spi->sck_bm;
+	spi->port->DIRCLR = spi->miso_bm;
+	
+	// want BSEL 7 and BSCALE -4
+	spi->com->BAUDCTRLA = 0; //130;
+	spi->com->BAUDCTRLB = 1; //USART_BSCALE3_bm | USART_BSCALE2_bm | USART_BSCALE1_bm | USART_BSCALE0_bm;
+	
+	spi->com->CTRLB = USART_TXEN_bm | USART_RXEN_bm;
+	
+	spi->com->CTRLC = USART_CMODE_MSPI_gc; // set to master spi mode
+	if(cpha != 0){
+		spi->com->CTRLC |= (1 << 1); // in master spi mode, this bit is clock polarity
+	}
+}
+
+void spi_txchar_polled(spiport_t *spi, uint8_t data){
+	while(!(spi->com->STATUS & USART_DREIF_bm));
+	spi->com->DATA = data;
+}
+
+void spi_txchars_polled(spiport_t *spi, uint8_t *data, uint8_t length){
+	pin_clear(spi->csn);
+	for(int i = 0; i < length; i ++){
+		spi_txchar_polled(spi, data[i]);
+		spi->com->STATUS |= USART_TXCIF_bm; // clear transmit complete flag 
+	}
+	while(!(spi->com->STATUS & USART_TXCIF_bm)); // wait for complete before
+	pin_set(spi->csn);
+}
+
+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/atkbldcdriver/atkbldcdriver/spiport.h b/embedded/atkbldcdriver/atkbldcdriver/spiport.h
new file mode 100644
index 0000000..cd5e5aa
--- /dev/null
+++ b/embedded/atkbldcdriver/atkbldcdriver/spiport.h
@@ -0,0 +1,35 @@
+/*
+ * spiport.h
+ *
+ * Created: 2/7/2018 10:51:52 AM
+ *  Author: Jake
+ */ 
+
+
+#ifndef SPIPORT_H_
+#define SPIPORT_H_
+
+#include <avr/io.h>
+#include "pin.h"
+
+typedef struct{
+	USART_t *com;
+	PORT_t *port;
+	
+	uint8_t miso_bm;
+	uint8_t mosi_bm;
+	uint8_t sck_bm;
+	
+	pin_t *csn;
+}spiport_t;
+
+void spi_init(spiport_t *spi, USART_t *com, PORT_t *port, uint8_t miso_bm, uint8_t mosi_bm, uint8_t sck_bm, pin_t *csn);
+
+void spi_start(spiport_t *spi, uint8_t cpha); // bits: 0: 8, 1: 32
+
+void spi_txchar_polled(spiport_t *spi, uint8_t data);
+void spi_txchars_polled(spiport_t *spi, uint8_t *data, uint8_t length);
+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/atkbldcdriver/atkbldcdriver/stepper.c b/embedded/atkbldcdriver/atkbldcdriver/stepper.c
new file mode 100644
index 0000000..a7d08a2
--- /dev/null
+++ b/embedded/atkbldcdriver/atkbldcdriver/stepper.c
@@ -0,0 +1,247 @@
+/*
+* stepper.c
+*
+* Created: 2/17/2018 5:39:34 PM
+*  Author: Jake
+*/
+
+#include "stepper.h"
+#include "hardware.h"
+#include "atkport.h"
+#include "atkhandler.h"
+#include "fastmath.h"
+
+void stepper_init(stepper_t *stepper, pin_t *step_pin, pin_t *dir_pin){
+	stepper->step_pin = step_pin;
+	stepper->dir_pin = dir_pin;
+	
+	stepper_reset(stepper);
+}
+
+void stepper_reset(stepper_t *stepper){
+	stepper->blockhead = 0;
+	stepper->blocktail = 0;
+	stepper->blocksize = BLOCKS_QUEUE_SIZE;
+
+	stepper->speed_period = 0;
+	stepper->accel_period = 0;
+	
+	stepper->speed = 0;
+	
+	stepper->position_ticks = 0;
+	stepper->position_accel_to = 0;
+	stepper->position_deccel_from = 0;
+}
+
+void stepper_steps(stepper_t *stepper, int32_t steps, uint32_t speed){
+	// not implemented atm
+}
+
+void stepper_new_block(uint8_t *packet, stepper_t *stepper, int32_t steps, uint32_t entryspeed, uint32_t accel, uint32_t accellength, uint32_t deccellength){
+	// does assignments and adds to queue
+	// track this address so that we can ack to it when the move is complete
+	// a sloppy copy, I'm sure
+	for(int i = 0; i < packet[0]; i ++){
+		stepper->block[stepper->blockhead].packet[i] = packet[i];
+	}
+	
+	// a real move
+	stepper->block[stepper->blockhead].is_nomove = 0;
+	
+	// TODO: should block the execution of this block while we do this, so that we
+	// have an interrupt safe ringbuffer
+	
+	// enforce no div/0
+	(entryspeed < 3) ? entryspeed = 3 : (0); //(0) is NOP: 3 is min steps/s due to timer resolution
+	(entryspeed > 187500) ? entryspeed = 187500 : (0); // no faster than this pls, else underneat timer resolution
+	// going to have to catch blocks which cause deceleration to 0 during deceleration phases !
+	stepper->block[stepper->blockhead].entry_speed = entryspeed;
+	
+	// do starting speed period
+	(accel < 3) ? accel = 3 : (0);
+	(accel > 187500) ? accel = 187500 : (0);
+	stepper->block[stepper->blockhead].accel_period = STEPTICKER_ONE_SECOND / accel;
+	
+	// set dir
+	if(steps < 0){
+		stepper->block[stepper->blockhead].dir = 0;
+		} else {
+		stepper->block[stepper->blockhead].dir = 1;
+	}
+	
+	// do lengths
+	stepper->block[stepper->blockhead].position_end = abs(steps);
+	stepper->block[stepper->blockhead].position_accel_to = accellength;
+	stepper->block[stepper->blockhead].position_deccel_from = deccellength;
+	
+	// ready set
+	stepper->block[stepper->blockhead].is_new = 1;
+	
+	// if there are currently no steps to make, we're not sure about the current step frequency, we'll set the period
+	// otherwise we're taking for granted that we've set this properly following the last move
+	if(stepper->blockhead == stepper->blocktail){
+		uint16_t newper = STEPTICKER_ONE_SECOND / entryspeed;
+		stepticker_newperiod(newper);
+		stepticker_reset();
+		uint16_t accper = STEPTICKER_ONE_SECOND / accel;
+		accelticker_newperiod(accper);
+		accelticker_reset();
+		pin_clear(&stlerr);
+	}
+	// increment block head ptr: should catch full queue HERE but not bothering
+	stepper->blockhead = fastModulo((stepper->blockhead + 1), BLOCKS_QUEUE_SIZE);
+}
+
+void stepper_new_wait(uint8_t *packet, stepper_t *stepper, int32_t steps, uint32_t speed){
+	for(int i = 0; i < packet[0]; i ++){
+		stepper->block[stepper->blockhead].packet[i] = packet[i];
+	}
+	
+	// we have a waiting block, we'll say accel is now = speed for supposed steps
+	stepper->block[stepper->blockhead].is_nomove = 1;
+	// still need to check this
+	(speed < 3) ? speed = 3 : (0);
+	(speed > 187500) ? speed = 187500 : (0);
+	// but we're going to wrap everything else in update() to avoid accel etc checks, we're just going to be counting
+	stepper->block[stepper->blockhead].entry_speed = speed;
+	stepper->block[stepper->blockhead].position_end = abs(steps);
+	stepper->block[stepper->blockhead].accel_period = STEPTICKER_ONE_SECOND - 1;
+	stepper->block[stepper->blockhead].position_accel_to = 0;
+	stepper->block[stepper->blockhead].position_deccel_from = abs(steps);
+	
+	// ready set
+	stepper->block[stepper->blockhead].is_new = 1;
+	
+	// if there are currently no steps to make, we're not sure about the current step frequency, we'll set the period
+	// otherwise we're taking for granted that we've set this properly following the last move
+	if(stepper->blockhead == stepper->blocktail){
+		pin_clear(&stlerr);
+		// could we just call stepper_update now?
+		uint16_t newper = STEPTICKER_ONE_SECOND / speed;
+		stepticker_newperiod(newper);
+		stepticker_reset();
+		uint16_t accper = STEPTICKER_ONE_SECOND - 1; // gets 16-bit truncated
+		accelticker_newperiod(accper);
+		accelticker_reset();
+		pin_clear(&stlerr);
+	}
+	
+	stepper->blockhead = fastModulo((stepper->blockhead + 1), BLOCKS_QUEUE_SIZE);
+}
+
+void stepper_updatesteps(stepper_t *stepper){
+	if(stepper->blockhead == stepper->blocktail){
+		// no steps to make, ringbuffer is empty
+		pin_set(&stlerr);
+		} else if(stepper->block[stepper->blocktail].position_end > stepper->position_ticks){
+		// we have somewhere to go
+		if(stepper->block[stepper->blocktail].is_new){
+			// if we're just starting this block, set the speed
+			stepper->speed = stepper->block[stepper->blocktail].entry_speed;
+			stepper->speed_period = STEPTICKER_ONE_SECOND / stepper->speed;
+			stepticker_newperiod(stepper->speed_period);
+			stepticker_reset();
+			
+			// and set the accel ticker
+			accelticker_newperiod(stepper->block[stepper->blocktail].accel_period);
+			accelticker_reset();
+			
+			// and set the dir
+			if(stepper->block[stepper->blocktail].dir > 0){
+				pin_set(stepper->dir_pin);
+				} else {
+				pin_clear(stepper->dir_pin);
+			}
+			// and distance was 0'd after last move
+			// and then clear this flag
+			stepper->block[stepper->blocktail].is_new = 0;
+		}
+		
+		// if there's steps to make, and this timer is firing, it's time to step!
+		if(!stepper->block[stepper->blocktail].is_nomove){
+			pin_toggle(stepper->step_pin);
+		}
+		
+		stepper->position_ticks ++;
+		
+		if(stepper->position_ticks < stepper->block[stepper->blocktail].position_accel_to){
+			stepper->accelstate = STEP_ACCELSTATE_ACCEL;
+			} else if (stepper->position_ticks > stepper->block[stepper->blocktail].position_deccel_from){
+			stepper->accelstate = STEP_ACCELSTATE_DECEL;
+			} else {
+			stepper->accelstate = STEP_ACCELSTATE_CRUISE;
+		}
+		
+		} else {
+		// looks a lot like we're done here
+		// send a reply for windowed transmission
+		// this is dirty because we're passing the packet (referenced here in the ringbuffer) by reference,
+		// properly return_packet should take a copy of the packet so that we can be done with it now, but *it* goes faster than *this* (almost for sure...)
+		// so, we shrugman for now
+		// apa_return_packet(stepper->block[stepper->blocktail].packet, 25);
+		uint8_t reply[12];
+		uint8_t replyLength = 0;
+		if(stepper->block[stepper->blocktail].is_nomove){
+			reply[0] = DELIM_KEY_WAIT;
+			reply[1] = 12;
+			replyLength = 2;
+			} else {
+			reply[0] = DELIM_KEY_TRAPEZOID;
+			int32_t stepsTaken = stepper->block[stepper->blocktail].position_end;
+			if(!stepper->block[stepper->blocktail].dir){
+				stepsTaken = -1 * stepsTaken;
+			}
+			reply[1] = stepsTaken >> 24;
+			reply[2] = stepsTaken >> 16;
+			reply[3] = stepsTaken >> 8;
+			reply[4] = stepsTaken;
+			replyLength = 5;
+		}
+		atk_reply_packet(stepper->block[stepper->blocktail].packet, reply, replyLength);
+		// increment ringbuffer along
+		stepper->blocktail = fastModulo((stepper->blocktail + 1), BLOCKS_QUEUE_SIZE);
+		stepper->position_ticks = 0; // clear so that we evaluate new block as having steps to make
+	}
+}
+
+void stepper_updateaccel(stepper_t *stepper){
+	// check for acceleration or deceleration
+	switch (stepper->accelstate){
+		case STEP_ACCELSTATE_ACCEL:
+		stepper->speed ++;
+		(stepper->speed > 187500) ? stepper->speed = 187500 : (0); // max speed due to timer res
+		stepper->speed_period = STEPTICKER_ONE_SECOND / stepper->speed;
+		stepticker_newperiod(stepper->speed_period);
+		break;
+		case STEP_ACCELSTATE_DECEL:
+		stepper->speed --;
+		(stepper->speed < 3) ? stepper->speed = 3 : (0); // min speed due to timer res
+		stepper->speed_period = STEPTICKER_ONE_SECOND / stepper->speed;
+		stepticker_newperiod(stepper->speed_period);
+		break;
+		case STEP_ACCELSTATE_CRUISE:
+		(0);
+		break;
+		default:
+		(0);
+		break;
+	}
+}
+
+void stepticker_newperiod(uint16_t per){
+	TCC0.PERBUFL = (uint8_t) per;
+	TCC0.PERBUFH = (uint8_t) (per >> 8);
+}
+
+void stepticker_reset(void){
+	TCC0.CTRLFSET = TC_CMD_RESTART_gc;
+}
+
+void accelticker_newperiod(uint16_t per){
+	TCC1.PERBUFL = (uint8_t) per;
+	TCC1.PERBUFH = (uint8_t) (per >> 8);
+}
+
+void accelticker_reset(void){
+	TCC1.CTRLFSET = TC_CMD_RESTART_gc;
+}
\ No newline at end of file
diff --git a/embedded/atkbldcdriver/atkbldcdriver/stepper.h b/embedded/atkbldcdriver/atkbldcdriver/stepper.h
new file mode 100644
index 0000000..e58e77c
--- /dev/null
+++ b/embedded/atkbldcdriver/atkbldcdriver/stepper.h
@@ -0,0 +1,95 @@
+/*
+ * stepper.h
+ *
+ * Created: 2/17/2018 5:39:45 PM
+ *  Author: Jake
+ */ 
+
+
+#ifndef STEPPER_H_
+#define STEPPER_H_
+
+#include "pin.h"
+
+#define BLOCKS_QUEUE_SIZE 16
+#define STEPTICKER_ONE_SECOND 187500 // one tick of timer is 5.3-- us
+#define STEP_ACCELSTATE_CRUISE 0
+#define STEP_ACCELSTATE_ACCEL 1
+#define STEP_ACCELSTATE_DECEL 2
+
+// one movement
+typedef struct {
+	// from whence you came
+	uint8_t packet[256]; // C quesion: how to do this properly with malloc() ? malloc() on embedded sys?
+	
+	// tracking
+	uint8_t is_new;
+	uint8_t is_nomove;
+	
+	// for what you do
+	uint8_t dir; // 0 or 1
+	uint32_t position_end; // in steps
+	uint32_t entry_speed;
+	uint32_t accel_period;
+	uint32_t position_accel_to;
+	uint32_t position_deccel_from;
+}block_t;
+
+// the stepper
+typedef struct {
+	pin_t *step_pin;
+	pin_t *dir_pin;
+	
+	// block ringbuffer
+	block_t block[BLOCKS_QUEUE_SIZE];
+	uint8_t blockhead;
+	uint8_t blocktail;
+	uint8_t blocksize;
+		
+	// tracking time periods
+	uint16_t speed_period; // meaning we have a min. step speed of STEPTICKER_ONE_SECOND / 2^16 ( ~ 2.86 s/s)
+	uint16_t accel_period;
+	
+	// tracking time for updates
+	uint8_t accelstate;
+	
+	// have to track speed to update accel
+	uint32_t speed;
+	
+	// targets
+	uint32_t position_ticks;
+	uint32_t position_accel_to;
+	uint32_t position_deccel_from;
+}stepper_t;
+
+void stepper_init(stepper_t *stepper, pin_t *step_pin, pin_t *dir_pin);
+
+void stepper_reset(stepper_t *stepper);
+
+// steps discrete, mm/min
+void stepper_steps(stepper_t *stepper, int32_t steps, uint32_t speed);
+
+// steps discrete, mm/min, mm/min/s (mm/s better but we want more discrete resolution)
+void stepper_new_block(uint8_t *packet, stepper_t *stepper, int32_t steps, uint32_t entryspeed, uint32_t accel, uint32_t accellength, uint32_t deccellength);
+
+void stepper_new_wait(uint8_t *packet, stepper_t *stepper, int32_t steps, uint32_t speed);
+
+void stepper_updatesteps(stepper_t *stepper);
+
+void stepper_updateaccel(stepper_t *stepper);
+
+void stepticker_newperiod(uint16_t per);
+
+void stepticker_reset(void);
+
+void accelticker_newperiod(uint16_t per);
+
+void accelticker_reset(void);
+
+/*
+step to-do
+// block ringbuffer, pull and reply blocks - architecture for network functions, generally?
+// doc this https://embeddedgurus.com/stack-overflow/2011/02/efficient-c-tip-13-use-the-modulus-operator-with-caution/ 
+*/
+
+#endif /* STEPPER_H_ */
\ No newline at end of file
diff --git a/embedded/atkbldcdriver/atkbldcdriver/uartport.c b/embedded/atkbldcdriver/atkbldcdriver/uartport.c
new file mode 100644
index 0000000..8b51d63
--- /dev/null
+++ b/embedded/atkbldcdriver/atkbldcdriver/uartport.c
@@ -0,0 +1,70 @@
+/*
+ * uartport.c
+ *
+ * Created: 6/18/2018 12:12:32 PM
+ *  Author: Jake
+ */ 
+
+#include "uartport.h"
+#include "hardware.h"
+
+void uart_init(uartport_t *up, USART_t *uart, PORT_t *port, uint8_t pinRX_bm, uint8_t pinTX_bm, ringbuffer_t *rbrx, ringbuffer_t *rbtx, pin_t *stlrx, pin_t *stltx){
+	up->uart = uart;
+	up->port = port;
+	up->pinRX_bm = pinRX_bm;
+	up->pinTX_bm = pinTX_bm;
+	up->rbrx = rbrx;
+	up->rbtx = rbtx;
+	up->stlrx = stlrx;
+	up->stltx = stltx;
+}
+
+void uart_start(uartport_t *up, uint8_t BAUDA, uint8_t BAUDB){
+	up->uart->BAUDCTRLA = BAUDA;
+	up->uart->BAUDCTRLB = BAUDB;
+	
+	up->uart->CTRLA |= USART_RXCINTLVL_MED_gc | USART_TXCINTLVL_OFF_gc | USART_DREINTLVL_OFF_gc;
+	
+	up->uart->CTRLB = USART_TXEN_bm | USART_RXEN_bm;
+	
+	// should try that parity
+	up->uart->CTRLC = USART_CMODE_ASYNCHRONOUS_gc | USART_PMODE_DISABLED_gc | USART_CHSIZE_8BIT_gc;
+	
+	up->port->DIRCLR = up->pinRX_bm;
+	up->port->DIRSET = up->pinTX_bm;
+	
+	pin_set(up->stlrx);
+	pin_set(up->stltx);
+}
+
+void uart_sendchar_polled(uartport_t *up, uint8_t data){
+	while(!(up->uart->STATUS & USART_DREIF_bm));
+	up->uart->DATA = data;
+}
+
+void uart_sendchar_buffered(uartport_t *up, uint8_t data){
+	rb_putchar(up->rbtx, data);
+	pin_clear(up->stltx);
+	up->uart->CTRLA |= USART_DREINTLVL_MED_gc;
+}
+
+void uart_sendchars_buffered(uartport_t *up, uint8_t *data, uint8_t length){
+	rb_putdata(up->rbtx, data, length);
+	pin_clear(up->stltx);
+	up->uart->CTRLA |= USART_DREINTLVL_MED_gc;
+}
+
+void uart_rxhandler(uartport_t *up){
+	uint8_t data = up->uart->DATA;
+	rb_putchar(up->rbrx, data);
+	pin_clear(up->stlrx);
+}
+
+void uart_txhandler(uartport_t *up){
+	if(!rb_empty(up->rbtx)){
+		up->uart->DATA = rb_get(up->rbtx);
+	} else {
+		up->uart->CTRLA = USART_DREINTLVL_OFF_gc | USART_RXCINTLVL_MED_gc;
+		pin_set(up->stltx);
+	}
+}
\ No newline at end of file
diff --git a/embedded/atkbldcdriver/atkbldcdriver/uartport.h b/embedded/atkbldcdriver/atkbldcdriver/uartport.h
new file mode 100644
index 0000000..72fa539
--- /dev/null
+++ b/embedded/atkbldcdriver/atkbldcdriver/uartport.h
@@ -0,0 +1,42 @@
+/*
+ * uartport.h
+ *
+ * Created: 6/18/2018 12:12:43 PM
+ *  Author: Jake
+ */ 
+
+
+#ifndef UARTPORT_H_
+#define UARTPORT_H_
+
+#include "avr/io.h"
+#include "ringbuffer.h"
+#include "pin.h"
+
+typedef struct{
+	USART_t *uart;
+	PORT_t *port;
+		
+	uint8_t pinRX_bm;
+	uint8_t pinTX_bm;
+	
+	ringbuffer_t *rbrx;
+	ringbuffer_t *rbtx;
+	
+	pin_t *stlrx;
+	pin_t *stltx;
+	
+}uartport_t;
+
+void uart_init(uartport_t *up, USART_t *uart, PORT_t *port, uint8_t pinRX_bm, uint8_t pinTX_bm, ringbuffer_t *rbrx, ringbuffer_t *rbtx, pin_t *stlrx, pin_t *stltx);
+
+void uart_start(uartport_t *up, uint8_t BAUDA, uint8_t BAUDB);
+
+void uart_sendchar_polled(uartport_t *up, uint8_t data);
+void uart_sendchar_buffered(uartport_t *up, uint8_t data);
+void uart_sendchars_buffered(uartport_t *up, uint8_t *data, uint8_t length);
+
+void uart_rxhandler(uartport_t *up);
+void uart_txhandler(uartport_t *up);
+
+#endif /* UARTPORT_H_ */
\ No newline at end of file
-- 
GitLab