diff --git a/README.md b/README.md
index 4fc545e8e2cbe3bdc6dd850ab488d7fd6fd97d6c..c9077bfd7582d6f2eb4227c1c0fbca46847c7e07 100644
--- a/README.md
+++ b/README.md
@@ -21,14 +21,15 @@ See [circuit chatter](/circuit) and [programming chatter](/embedded).
 
 # Circuit Notes 17
 
- - crystal
- - qfn64 footprint update!
- - power conn. size wrong, check update
- - pullup (pulldown?) on EN, not step
+ - after power pad update, gnd route is unhappy
+ - capacitor 10uf underneath phy pad
 
 # Circuit Notes 23
 
  - mounting hole beside ports RIP, move across to not GND motor to port shield with screw
+ - heat-sinkableness would be *very* rad considering 101c temp. at 1A 
+  - 2oz if JLCPCB makes this easy 
+ - 497-15314-1-ND or DMC4029SK4-13DICT-ND for new fets / better heat 
 
 ## MKStepper17
 
diff --git a/circuit/atkstepper17/atkstepper17.brd b/circuit/atkstepper17/atkstepper17.brd
index 39cd619d6b243d41053e9e7d97c2ce4cd821ab10..4a7f7a8850d72fa154546831c41ea02362c97fb7 100644
--- a/circuit/atkstepper17/atkstepper17.brd
+++ b/circuit/atkstepper17/atkstepper17.brd
@@ -3,7 +3,7 @@
 <eagle version="9.0.0">
 <drawing>
 <settings>
-<setting alwaysvectorfont="yes"/>
+<setting alwaysvectorfont="no"/>
 <setting verticaltext="up"/>
 </settings>
 <grid distance="0.1" unitdist="mm" unit="mm" style="lines" multiple="1" display="yes" altdistance="1" altunitdist="mm" altunit="mm"/>
@@ -203,56 +203,56 @@ sprint and then pass on</text>
 <library name="power">
 <packages>
 <package name="PWRPAD_M3-PEM-MOUNT">
-<pad name="P$1" x="0" y="0" drill="4.1" diameter="6.2" thermals="no"/>
+<pad name="P$1" x="0" y="0" drill="4.4" diameter="7" thermals="no"/>
 <polygon width="0.127" layer="31">
-<vertex x="-0.6" y="3"/>
-<vertex x="0.6" y="3"/>
+<vertex x="-0.6" y="3.6"/>
+<vertex x="0.6" y="3.6"/>
 <vertex x="0.4" y="2.1"/>
 <vertex x="-0.4" y="2.1"/>
 </polygon>
 <polygon width="0.127" layer="31">
-<vertex x="0.6" y="-3"/>
-<vertex x="-0.6" y="-3"/>
+<vertex x="0.6" y="-3.6"/>
+<vertex x="-0.6" y="-3.6"/>
 <vertex x="-0.4" y="-2.1"/>
 <vertex x="0.4" y="-2.1"/>
 </polygon>
 <polygon width="0.127" layer="31">
-<vertex x="-3" y="-0.6"/>
-<vertex x="-3" y="0.6"/>
+<vertex x="-3.6" y="-0.6"/>
+<vertex x="-3.6" y="0.6"/>
 <vertex x="-2.1" y="0.4"/>
 <vertex x="-2.1" y="-0.4"/>
 </polygon>
 <polygon width="0.127" layer="31">
-<vertex x="3" y="0.6"/>
-<vertex x="3" y="-0.6"/>
+<vertex x="3.6" y="0.6"/>
+<vertex x="3.6" y="-0.6"/>
 <vertex x="2.1" y="-0.4"/>
 <vertex x="2.1" y="0.4"/>
 </polygon>
 <polygon width="0.127" layer="31">
-<vertex x="-2.55269375" y="1.73136875"/>
-<vertex x="-1.704165625" y="2.579896875"/>
+<vertex x="-2.95269375" y="2.13136875"/>
+<vertex x="-2.104165625" y="2.979896875"/>
 <vertex x="-1.19203125" y="1.784921875"/>
 <vertex x="-1.75771875" y="1.2192375"/>
 </polygon>
 <polygon width="0.127" layer="31">
-<vertex x="2.59705625" y="-1.72131875"/>
-<vertex x="1.748528125" y="-2.569846875"/>
+<vertex x="2.99705625" y="-2.12131875"/>
+<vertex x="2.148528125" y="-2.969846875"/>
 <vertex x="1.23639375" y="-1.774871875"/>
 <vertex x="1.80208125" y="-1.2091875"/>
 </polygon>
 <polygon width="0.127" layer="31">
-<vertex x="-1.704165625" y="-2.569846875"/>
-<vertex x="-2.55269375" y="-1.72131875"/>
+<vertex x="-2.104165625" y="-2.969846875"/>
+<vertex x="-2.95269375" y="-2.12131875"/>
 <vertex x="-1.75771875" y="-1.2091875"/>
 <vertex x="-1.19203125" y="-1.774871875"/>
 </polygon>
 <polygon width="0.127" layer="31">
-<vertex x="1.748528125" y="2.579896875"/>
-<vertex x="2.59705625" y="1.73136875"/>
+<vertex x="2.148528125" y="2.979896875"/>
+<vertex x="2.99705625" y="2.13136875"/>
 <vertex x="1.80208125" y="1.2192375"/>
 <vertex x="1.23639375" y="1.784921875"/>
 </polygon>
-<circle x="0" y="0" radius="3" width="0.125" layer="51"/>
+<circle x="0" y="0" radius="3.5" width="0.125" layer="51"/>
 </package>
 <package name="PWRPAD_3-25MM">
 <pad name="P$1" x="0" y="0" drill="3.25" diameter="5.75" thermals="no"/>
@@ -1859,10 +1859,9 @@ design rules under a new name.</description>
 <wire x1="10.3714" y1="23.79635625" x2="9.665" y2="24.50275625" width="0.1524" layer="1"/>
 <contactref element="R8" pad="2"/>
 <contactref element="U1" pad="1"/>
-<wire x1="12.7528" y1="34.6382" x2="12.1640125" y2="34.0494125" width="0.1524" layer="1"/>
-<wire x1="15.2472" y1="34.6382" x2="15.7382" y2="34.1472" width="0.1524" layer="1"/>
+<wire x1="15.2472" y1="34.6382" x2="15.2927" y2="34.5927" width="0.1524" layer="1"/>
+<wire x1="15.2927" y1="34.5927" x2="15.7382" y2="34.1472" width="0.1524" layer="1"/>
 <wire x1="15.7382" y1="34.1472" x2="15.7382" y2="33.5525125" width="0.1524" layer="1"/>
-<wire x1="12.7528" y1="34.6382" x2="15.2472" y2="34.6382" width="0.1524" layer="1"/>
 <wire x1="17.8825625" y1="31.40815" x2="18.20245625" y2="31.40815" width="0.1524" layer="1"/>
 <via x="18.20245625" y="31.40815" extent="1-16" drill="0.3"/>
 <wire x1="18.20245625" y1="31.40815" x2="18.42240625" y2="31.1882" width="0.1524" layer="16"/>
@@ -1899,14 +1898,13 @@ design rules under a new name.</description>
 <wire x1="10.2858" y1="31.78005" x2="10.2858" y2="32.23245" width="0.1524" layer="1"/>
 <wire x1="10.2858" y1="32.23245" x2="9.76105" y2="32.7572" width="0.1524" layer="1"/>
 <wire x1="9.76105" y1="32.7572" x2="10.08094375" y2="32.7572" width="0.1524" layer="16"/>
-<wire x1="10.08094375" y1="32.7572" x2="11.111871875" y2="33.788128125" width="0.1524" layer="16"/>
+<wire x1="10.08094375" y1="32.7572" x2="11.14695625" y2="33.8232125" width="0.1524" layer="16"/>
 <wire x1="9.665" y1="24.50275625" x2="9.665" y2="30.21065625" width="0.1524" layer="1"/>
-<wire x1="12.1640125" y1="34.0494125" x2="12.0356" y2="34.0494125" width="0.1524" layer="1"/>
-<via x="12.0356" y="34.0494125" extent="1-16" drill="0.3"/>
-<wire x1="12.0356" y1="34.0494125" x2="12.0356" y2="34.0356" width="0.1524" layer="16"/>
-<wire x1="12.0356" y1="34.0356" x2="11.8232125" y2="33.8232125" width="0.1524" layer="16"/>
-<wire x1="11.14695625" y1="33.8232125" x2="11.111871875" y2="33.788128125" width="0.1524" layer="16"/>
-<wire x1="11.8232125" y1="33.8232125" x2="11.14695625" y2="33.8232125" width="0.1524" layer="16"/>
+<wire x1="14.4322125" y1="33.8232125" x2="15.407146875" y2="34.798146875" width="0.1524" layer="16"/>
+<via x="15.407146875" y="34.798146875" extent="1-16" drill="0.3"/>
+<wire x1="15.407146875" y1="34.798146875" x2="15.2927" y2="34.6837" width="0.1524" layer="1"/>
+<wire x1="15.2927" y1="34.6837" x2="15.2927" y2="34.5927" width="0.1524" layer="1"/>
+<wire x1="11.14695625" y1="33.8232125" x2="14.4322125" y2="33.8232125" width="0.1524" layer="16"/>
 </signal>
 <signal name="TMC_CSN">
 <contactref element="U2" pad="2"/>
@@ -2142,7 +2140,8 @@ design rules under a new name.</description>
 <wire x1="10.0666" y1="23.6701" x2="8.7867" y2="24.95" width="0.1524" layer="1"/>
 <wire x1="8.7867" y1="24.95" x2="8.4" y2="24.95" width="0.1524" layer="1"/>
 <wire x1="8.4" y1="24.95" x2="8.25" y2="25.1" width="0.1524" layer="1"/>
-<wire x1="7" y1="25.1" x2="8.25" y2="25.1" width="0" layer="19" extent="1-1"/>
+<wire x1="7" y1="25.1" x2="7.15" y2="24.95" width="0.1524" layer="1"/>
+<wire x1="7.15" y1="24.95" x2="8.4" y2="24.95" width="0.1524" layer="1"/>
 </signal>
 <signal name="STLERR">
 <contactref element="R2" pad="1"/>
diff --git a/circuit/atkstepper17/atkstepper17.sch b/circuit/atkstepper17/atkstepper17.sch
index 1ae89557ba3392ec5b6643490d8118d5171aab39..734ededc9e4d4a0061a67627eca6d9ef0f10fedb 100644
--- a/circuit/atkstepper17/atkstepper17.sch
+++ b/circuit/atkstepper17/atkstepper17.sch
@@ -3,7 +3,7 @@
 <eagle version="9.0.0">
 <drawing>
 <settings>
-<setting alwaysvectorfont="yes"/>
+<setting alwaysvectorfont="no"/>
 <setting verticaltext="up"/>
 </settings>
 <grid distance="0.1" unitdist="inch" unit="inch" style="lines" multiple="1" display="yes" altdistance="0.01" altunitdist="inch" altunit="inch"/>
@@ -181,56 +181,56 @@
 <pad name="P$1" x="0" y="0" drill="2.05" diameter="3.8" thermals="no"/>
 </package>
 <package name="PWRPAD_M3-PEM-MOUNT">
-<pad name="P$1" x="0" y="0" drill="4.1" diameter="6.2" thermals="no"/>
+<pad name="P$1" x="0" y="0" drill="4.4" diameter="7" thermals="no"/>
 <polygon width="0.127" layer="31">
-<vertex x="-0.6" y="3"/>
-<vertex x="0.6" y="3"/>
+<vertex x="-0.6" y="3.6"/>
+<vertex x="0.6" y="3.6"/>
 <vertex x="0.4" y="2.1"/>
 <vertex x="-0.4" y="2.1"/>
 </polygon>
 <polygon width="0.127" layer="31">
-<vertex x="0.6" y="-3"/>
-<vertex x="-0.6" y="-3"/>
+<vertex x="0.6" y="-3.6"/>
+<vertex x="-0.6" y="-3.6"/>
 <vertex x="-0.4" y="-2.1"/>
 <vertex x="0.4" y="-2.1"/>
 </polygon>
 <polygon width="0.127" layer="31">
-<vertex x="-3" y="-0.6"/>
-<vertex x="-3" y="0.6"/>
+<vertex x="-3.6" y="-0.6"/>
+<vertex x="-3.6" y="0.6"/>
 <vertex x="-2.1" y="0.4"/>
 <vertex x="-2.1" y="-0.4"/>
 </polygon>
 <polygon width="0.127" layer="31">
-<vertex x="3" y="0.6"/>
-<vertex x="3" y="-0.6"/>
+<vertex x="3.6" y="0.6"/>
+<vertex x="3.6" y="-0.6"/>
 <vertex x="2.1" y="-0.4"/>
 <vertex x="2.1" y="0.4"/>
 </polygon>
 <polygon width="0.127" layer="31">
-<vertex x="-2.55269375" y="1.73136875"/>
-<vertex x="-1.704165625" y="2.579896875"/>
+<vertex x="-2.95269375" y="2.13136875"/>
+<vertex x="-2.104165625" y="2.979896875"/>
 <vertex x="-1.19203125" y="1.784921875"/>
 <vertex x="-1.75771875" y="1.2192375"/>
 </polygon>
 <polygon width="0.127" layer="31">
-<vertex x="2.59705625" y="-1.72131875"/>
-<vertex x="1.748528125" y="-2.569846875"/>
+<vertex x="2.99705625" y="-2.12131875"/>
+<vertex x="2.148528125" y="-2.969846875"/>
 <vertex x="1.23639375" y="-1.774871875"/>
 <vertex x="1.80208125" y="-1.2091875"/>
 </polygon>
 <polygon width="0.127" layer="31">
-<vertex x="-1.704165625" y="-2.569846875"/>
-<vertex x="-2.55269375" y="-1.72131875"/>
+<vertex x="-2.104165625" y="-2.969846875"/>
+<vertex x="-2.95269375" y="-2.12131875"/>
 <vertex x="-1.75771875" y="-1.2091875"/>
 <vertex x="-1.19203125" y="-1.774871875"/>
 </polygon>
 <polygon width="0.127" layer="31">
-<vertex x="1.748528125" y="2.579896875"/>
-<vertex x="2.59705625" y="1.73136875"/>
+<vertex x="2.148528125" y="2.979896875"/>
+<vertex x="2.99705625" y="2.13136875"/>
 <vertex x="1.80208125" y="1.2192375"/>
 <vertex x="1.23639375" y="1.784921875"/>
 </polygon>
-<circle x="0" y="0" radius="3" width="0.125" layer="51"/>
+<circle x="0" y="0" radius="3.5" width="0.125" layer="51"/>
 </package>
 <package name="QFN36-5X6">
 <description>&lt;b&gt;QFN 32&lt;/b&gt; 5 x 5 mm&lt;p&gt;
@@ -777,6 +777,9 @@ Source: http://datasheets.maxim-ic.com/en/ds/MAX7042.pdf</description>
 <rectangle x1="0.7" y1="-2.4" x2="1.3" y2="-2.1" layer="31"/>
 <rectangle x1="-0.3" y1="-2.4" x2="0.3" y2="-2.1" layer="31"/>
 </package>
+<package name="PWRPAD_3-25MM-SKINNY">
+<pad name="P$1" x="0" y="0" drill="3.25" diameter="5.35" thermals="no"/>
+</package>
 </packages>
 <symbols>
 <symbol name="PWRPAD">
@@ -877,6 +880,14 @@ Source: http://datasheets.maxim-ic.com/en/ds/MAX7042.pdf</description>
 <technology name=""/>
 </technologies>
 </device>
+<device name="M3-SKINNY" package="PWRPAD_3-25MM-SKINNY">
+<connects>
+<connect gate="G$1" pin="PWRPAD" pad="P$1"/>
+</connects>
+<technologies>
+<technology name=""/>
+</technologies>
+</device>
 </devices>
 </deviceset>
 <deviceset name="TMC2130" prefix="U">
diff --git a/circuit/atkstepper17/eagle.epf b/circuit/atkstepper17/eagle.epf
index 3449f46b6d370e6ba81d509ecaac46cf31e1174d..e20b1d67aa7efced57531fa9fdadf747773b74c6 100644
--- a/circuit/atkstepper17/eagle.epf
+++ b/circuit/atkstepper17/eagle.epf
@@ -17,7 +17,6 @@ UsedLibrary="D:/Dropbox (Personal)/CBA/doc/libraries/eagle/motors.lbr"
 UsedLibrary="D:/Dropbox (Personal)/CBA/doc/libraries/eagle/power.lbr"
 UsedLibrary="D:/Dropbox (Personal)/CBA/doc/libraries/eagle/sensor.lbr"
 UsedLibrary="D:/Dropbox (Personal)/CBA/doc/libraries_jake/eagle/sparkfun/SparkFun-Connectors.lbr"
-UsedLibrary="D:/Dropbox (Personal)/CBA/doc/libraries_jake/eagle/marekr/borkedlabs-passives.lbr"
 UsedLibrary="D:/Dropbox (Personal)/CBA/doc/libraries_jake/eagle/jake/tag-connect-2050.lbr"
 UsedLibrary="C:/EAGLE 8.3.2/lbr/ltspice/Comparators.lbr"
 UsedLibrary="C:/EAGLE 8.3.2/lbr/ltspice/Digital.lbr"
@@ -35,12 +34,13 @@ UsedLibrary="C:/EAGLE 8.3.2/lbr/ltspice/lt-spice-simulation.lbr"
 UsedLibrary="C:/EAGLE 8.3.2/lbr/ltspice/lt-supply.lbr"
 UsedLibrary="C:/EAGLE 8.3.2/lbr/ltspice/rload.lbr"
 UsedLibrary="C:/EAGLE 8.3.2/lbr/ltspice/sym.lbr"
+UsedLibrary="D:/Dropbox (Personal)/CBA/doc/libraries_jake/eagle/marekr/borkedlabs-passives.lbr"
 
 [Win_1]
 Type="Schematic Editor"
 Number=1
 File="atkstepper17.sch"
-View="13.4383 104.876 242.064 267.489"
+View="80.8728 52.8383 355.224 247.974"
 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"
@@ -79,14 +79,14 @@ ArcDirection=0
 AddLevel=2
 PadsSameType=0
 Layer=91
-Views=" 1: 13.4383 104.876 242.064 267.489"
+Views=" 1: 80.8728 52.8383 355.224 247.974"
 Sheet="1"
 
 [Win_2]
 Type="Board Editor"
 Number=2
 File="atkstepper17.brd"
-View="-6.59981 -11.5805 57.317 53.9612"
+View="11.3999 -6.36849 64.664 48.2496"
 WireWidths=" 0.0762 0.1016 0.127 0.15 0.2 0.254 0.3048 0.4064 0.508 0.6096 1.016 2.54 0.8128 1.27 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.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"
@@ -124,14 +124,14 @@ SwapLevel=0
 ArcDirection=0
 AddLevel=2
 PadsSameType=0
-Layer=16
+Layer=1
 
 [Win_3]
 Type="Control Panel"
 Number=0
 
 [Desktop]
-Screen="6000 2160"
+Screen="3840 1080"
 Window="Win_1"
 Window="Win_2"
 Window="Win_3"
diff --git a/circuit/atkstepper23/eagle.epf b/circuit/atkstepper23/eagle.epf
index 2f1918cdfc3500aede00826dfbe1989f67506692..242a224234857a4ae6d8dc73cb2a2d0b9897b94b 100644
--- a/circuit/atkstepper23/eagle.epf
+++ b/circuit/atkstepper23/eagle.epf
@@ -41,7 +41,7 @@ UsedLibrary="D:/Dropbox (Personal)/CBA/doc/libraries_jake/eagle/marekr/borkedlab
 Type="Schematic Editor"
 Number=1
 File="atkstepper23.sch"
-View="21.5059 117.164 186.993 223.802"
+View="-14.9679 131.343 223.333 284.902"
 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"
@@ -80,14 +80,14 @@ ArcDirection=0
 AddLevel=2
 PadsSameType=0
 Layer=97
-Views=" 1: 21.5059 117.164 186.993 223.802"
+Views=" 1: -14.9679 131.343 223.333 284.902"
 Sheet="1"
 
 [Win_2]
 Type="Board Editor"
 Number=2
 File="atkstepper23.brd"
-View="30.3953 18.0172 51.4583 40.4406"
+View="9.59723 -14.0936 85.0697 66.2535"
 WireWidths=" 0.0762 0.1016 0.127 0.15 0.2 0.2032 0.254 0.3048 0.508 1.016 1.27 2.54 0.8128 0.6096 0.4064 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"
diff --git a/embedded/atkstepper17/atkstepper17/atkhandler.c b/embedded/atkstepper17/atkstepper17/atkhandler.c
new file mode 100644
index 0000000000000000000000000000000000000000..b0decb920d6defc5f52df04eba9136cca660028b
--- /dev/null
+++ b/embedded/atkstepper17/atkstepper17/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:
+						// TODO
+						break;
+					
+					case DELIM_KEY_TRAPEZOID:
+						//pin_toggle(&stlerr);
+						if(i + 12 > length){
+							i ++;
+						} else {
+							// in steps (discrete)
+							steps = ((int32_t)packet[i+1] << 24) | ((int32_t)packet[i+2] << 16) | ((int32_t)packet[i+3] << 8) | (int32_t)packet[i+4];
+							// in steps/s
+							uint32_t entryspeed = ((int32_t)packet[i+5] << 24) | ((int32_t)packet[i+6] << 16) | ((int32_t)packet[i+7] << 8) | (int32_t)packet[i+8];
+							// in steps/min/s
+							uint32_t accel = ((int32_t)packet[i+9] << 24) | ((int32_t)packet[i+10] << 16) | ((int32_t)packet[i+11] << 8) | (int32_t)packet[i+12];
+							// in steps/min
+							uint32_t accellength = ((int32_t)packet[i+13] << 24) | ((int32_t)packet[i+14] << 16) | ((int32_t)packet[i+15] << 8) | (int32_t)packet[i+16];
+							// in steps/min
+							uint32_t deccellength = ((int32_t)packet[i+17] << 24) | ((int32_t)packet[i+18] << 16) | (int32_t)(packet[i+19] << 8) | (int32_t)packet[i+20];
+							// do the business
+							i += 21;
+							stepper_new_block(packet, &stepper, steps, entryspeed, accel, accellength, deccellength);
+						}
+						break;
+					
+					case DELIM_KEY_WAIT:
+						if(i + 8 > length){
+							i ++;
+						} else {
+							steps = ((int32_t)packet[i+1] << 24) | ((int32_t)packet[i+2] << 16) | ((int32_t)packet[i+3] << 8) | (int32_t)packet[i+4];
+							// in steps/s
+							uint32_t speed = ((int32_t)packet[i+5] << 24) | ((int32_t)packet[i+6] << 16) | ((int32_t)packet[i+7] << 8) | (int32_t)packet[i+8];
+							i += 8;
+							stepper_new_wait(packet, &stepper, steps, speed);
+						}
+											
+					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/atkstepper17/atkstepper17/atkhandler.h b/embedded/atkstepper17/atkstepper17/atkhandler.h
new file mode 100644
index 0000000000000000000000000000000000000000..1b6879aa507d2433667ff90eda849c58a8c25f65
--- /dev/null
+++ b/embedded/atkstepper17/atkstepper17/atkhandler.h
@@ -0,0 +1,28 @@
+/*
+ * 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
+
+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/atkstepper17/atkstepper17/atkport.c b/embedded/atkstepper17/atkstepper17/atkport.c
new file mode 100644
index 0000000000000000000000000000000000000000..65b80e0eddbf8a8a2e0a8a941c5d8a86e2d25a02
--- /dev/null
+++ b/embedded/atkstepper17/atkstepper17/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/atkstepper17/atkstepper17/atkport.h b/embedded/atkstepper17/atkstepper17/atkport.h
new file mode 100644
index 0000000000000000000000000000000000000000..c99365fd2000dc1bec261aa932808e9e23bdf5d3
--- /dev/null
+++ b/embedded/atkstepper17/atkstepper17/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/atkstepper17/atkstepper17/fastmath.c b/embedded/atkstepper17/atkstepper17/fastmath.c
new file mode 100644
index 0000000000000000000000000000000000000000..91d749c7d4d98df07849944e54772b75852596fc
--- /dev/null
+++ b/embedded/atkstepper17/atkstepper17/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/atkstepper17/atkstepper17/fastmath.h b/embedded/atkstepper17/atkstepper17/fastmath.h
new file mode 100644
index 0000000000000000000000000000000000000000..d1c2cb1b34048c184621f5446f18901c8a8a1272
--- /dev/null
+++ b/embedded/atkstepper17/atkstepper17/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/atkstepper17/atkstepper17/hardware.h b/embedded/atkstepper17/atkstepper17/hardware.h
new file mode 100644
index 0000000000000000000000000000000000000000..4370e1a422debbcc75cc0ef87023b094b559badc
--- /dev/null
+++ b/embedded/atkstepper17/atkstepper17/hardware.h
@@ -0,0 +1,74 @@
+/*
+ * 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 "tmc26x.h"
+#include "stepper.h"
+
+// results in 1MBaud
+#define SYSTEM_BAUDA 3
+#define SYSTEM_BAUDB 0
+#define SYSTEM_NUM_UPS 2
+
+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;
+
+// UP1
+
+ringbuffer_t up1rbrx;
+ringbuffer_t up1rbtx;
+
+uartport_t up1;
+
+pin_t up1rxled;
+pin_t up1txled;
+
+atkport_t atkp1;
+
+// UPS
+
+uartport_t *ups[SYSTEM_NUM_UPS];
+
+// Stepper
+// SPI
+
+spiport_t spitmc;
+pin_t spicspin;
+
+pin_t tmcen;
+pin_t tmcsg;
+pin_t step;
+pin_t dir;
+
+tmc26_t tmc;
+
+stepper_t stepper;
+
+unsigned long timebase;
+
+#endif /* HARDWARE_H_ */
\ No newline at end of file
diff --git a/embedded/atkstepper17/atkstepper17/main.c b/embedded/atkstepper17/atkstepper17/main.c
new file mode 100644
index 0000000000000000000000000000000000000000..f81f96d8ae1a65c64bdbc68a019f69cada303a07
--- /dev/null
+++ b/embedded/atkstepper17/atkstepper17/main.c
@@ -0,0 +1,147 @@
+/*
+* 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"
+
+// stlclk PA0
+// stlerr PA1
+
+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);
+	atkport_init(&atkp1, 1, &up1);
+}
+
+void stephardware_init(void){
+	pin_init(&spicspin, &PORTC, PIN4_bm, 4, 1);
+	spi_init(&spitmc, &USARTC1, &PORTC, PIN6_bm, PIN7_bm, PIN5_bm, &spicspin);
+	spi_start(&spitmc, 0);
+	
+	pin_init(&tmcen, &PORTC, PIN3_bm, 3, 1);
+	pin_init(&tmcsg, &PORTA, PIN2_bm, 2, 0);
+	pin_init(&step, &PORTA, PIN0_bm, 0, 1);
+	pin_init(&dir, &PORTA, PIN1_bm, 1, 1);
+	
+	tmc26_init(&tmc, &spitmc, &tmcen, &tmcsg);
+	
+	stepper_init(&stepper, &step, &dir);
+}
+
+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, &PORTF, PIN7_bm, 7, 1);
+	pin_init(&stlerr, &PORTF, PIN6_bm, 6, 1);
+	pin_set(&stlerr);
+	pin_set(&stlclk);
+
+	// stepper business
+	stephardware_init();
+	
+	tmc26_start(&tmc);
+	tmc26_enable(&tmc);
+	
+	tickers_init();
+
+	// runtime globals
+	uint32_t tck = 0;
+
+	while (1)
+	{
+		atkport_scan(&atkp0, 2);
+		atkport_scan(&atkp1, 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);
+}
+
+ISR(USARTE0_RXC_vect){
+	uart_rxhandler(&up1);
+}
+
+ISR(USARTE0_DRE_vect){
+	uart_txhandler(&up1);
+}
\ No newline at end of file
diff --git a/embedded/atkstepper17/atkstepper17/pin.c b/embedded/atkstepper17/atkstepper17/pin.c
new file mode 100644
index 0000000000000000000000000000000000000000..071e771a5468cccc6c73bdf445068095b3dd07af
--- /dev/null
+++ b/embedded/atkstepper17/atkstepper17/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/atkstepper17/atkstepper17/pin.h b/embedded/atkstepper17/atkstepper17/pin.h
new file mode 100644
index 0000000000000000000000000000000000000000..d7ddab6e023abc0744743c66bfc7686fad2b3bac
--- /dev/null
+++ b/embedded/atkstepper17/atkstepper17/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/atkstepper17/atkstepper17/ringbuffer.c b/embedded/atkstepper17/atkstepper17/ringbuffer.c
new file mode 100644
index 0000000000000000000000000000000000000000..a77dc50785ca9153ce3d05a656dd190bb0a59d05
--- /dev/null
+++ b/embedded/atkstepper17/atkstepper17/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/atkstepper17/atkstepper17/ringbuffer.h b/embedded/atkstepper17/atkstepper17/ringbuffer.h
new file mode 100644
index 0000000000000000000000000000000000000000..921c8ba7717b5eedc76175a83f87db0308e6ca5e
--- /dev/null
+++ b/embedded/atkstepper17/atkstepper17/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/atkstepper17/atkstepper17/spiport.c b/embedded/atkstepper17/atkstepper17/spiport.c
new file mode 100644
index 0000000000000000000000000000000000000000..a7698bc628f04f00f6730ef8df697754c951b9ed
--- /dev/null
+++ b/embedded/atkstepper17/atkstepper17/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/atkstepper17/atkstepper17/spiport.h b/embedded/atkstepper17/atkstepper17/spiport.h
new file mode 100644
index 0000000000000000000000000000000000000000..cd5e5aa10ae4d4a5f85c73acd785d2b727d67650
--- /dev/null
+++ b/embedded/atkstepper17/atkstepper17/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/atkstepper17/atkstepper17/stepper.c b/embedded/atkstepper17/atkstepper17/stepper.c
new file mode 100644
index 0000000000000000000000000000000000000000..8fb78ee0e1bb7ecd35673bbbb1f610a61311a80b
--- /dev/null
+++ b/embedded/atkstepper17/atkstepper17/stepper.c
@@ -0,0 +1,237 @@
+/*
+* 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[2];
+		if(stepper->block[stepper->blocktail].is_nomove){
+			reply[0] = DELIM_KEY_WAIT;
+			reply[1] = 12;
+			} else {
+			reply[0] = DELIM_KEY_TRAPEZOID;
+			reply[1] = 24;
+		}
+		atk_reply_packet(stepper->block[stepper->blocktail].packet, reply, 2);
+		// 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/atkstepper17/atkstepper17/stepper.h b/embedded/atkstepper17/atkstepper17/stepper.h
new file mode 100644
index 0000000000000000000000000000000000000000..e58e77cb6114d131f10cb6536b210d20e440b617
--- /dev/null
+++ b/embedded/atkstepper17/atkstepper17/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/atkstepper17/atkstepper17/tmc26x.c b/embedded/atkstepper17/atkstepper17/tmc26x.c
new file mode 100644
index 0000000000000000000000000000000000000000..da44efd69cc754cf05861e8badc58aaef49662e6
--- /dev/null
+++ b/embedded/atkstepper17/atkstepper17/tmc26x.c
@@ -0,0 +1,74 @@
+/*
+ * tmc26x.c
+ *
+ * Created: 2/7/2018 10:17:39 PM
+ *  Author: Jake
+ */ 
+
+#include "tmc26x.h"
+
+void tmc26_init(tmc26_t *tmc, spiport_t *spi, pin_t *en, pin_t *sg){	
+	tmc->spi = spi;
+	tmc->en_pin = en;
+	tmc->sg_pin = sg;
+}
+
+void tmc26_write(tmc26_t *tmc, uint32_t word){
+	// takes a 20-bit TMC ready word and writes it on the SPI port, using three 8-bit words
+	//word = word << 4; // go left for 4 empty bits at the end of byte 3 (20 not 24 bit 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(tmc->spi, bytes, 3);
+}
+
+void tmc26_start(tmc26_t *tmc){
+	pin_output(tmc->en_pin);
+	//pin_input(tmc->sg_pin);
+	tmc26_disable(tmc); // turnt off
+	
+	// address, slope control hi and lo to minimum, short to ground protection on, short to gnd timer 3.2us,
+	// enable step/dir, sense resistor full scale current voltage is 0.16mv, readback stallguard2 data, reserved
+	uint32_t drvconf = 0b11100000000000110000; 
+	tmc26_write(tmc, drvconf);
+	
+	// address, sgfilt off, threshold value, current scaling (5-bit value appended)
+	uint32_t sgthresh_mask = 0b00000111111100000000;
+	int32_t sgthres_val = 60;
+	uint32_t cscale_mask = 0b00000000000000011111;
+	uint32_t cscale_val = 6;
+	uint32_t sgcsconf = 0b11010000000000000000 | ((sgthres_val << 8) & sgthresh_mask) | (cscale_val & cscale_mask);
+	tmc26_write(tmc, sgcsconf);
+	
+	// turning coolstep off
+	uint32_t smarten = 0b10100000000000000000;
+	tmc26_write(tmc, smarten);
+	
+	// times, delays, cycle mode
+	uint32_t chopconf = 0b10011000001000010011;
+	tmc26_write(tmc, chopconf);
+	
+	// 9th bit is intpol, 8th is dedge, last 4 are microstepping
+	// 0101 8
+	// 0100 16
+	// 0011 32
+	// 0010 64
+	// 0001 128
+	// 0000 256
+	uint32_t drvctrl = 0b00000000001100000100;
+	tmc26_write(tmc, drvctrl);
+}
+
+void tmc26_update(tmc26_t *tmc){
+	uint32_t smarten = 0b10100000000000000000;
+	tmc26_write(tmc, smarten);
+}
+
+void tmc26_enable(tmc26_t *tmc){
+	pin_clear(tmc->en_pin);
+}
+
+void tmc26_disable(tmc26_t *tmc){
+	pin_set(tmc->en_pin);
+}
\ No newline at end of file
diff --git a/embedded/atkstepper17/atkstepper17/tmc26x.h b/embedded/atkstepper17/atkstepper17/tmc26x.h
new file mode 100644
index 0000000000000000000000000000000000000000..a9f1e61edde58a1715c1639bb79bde584ca564a3
--- /dev/null
+++ b/embedded/atkstepper17/atkstepper17/tmc26x.h
@@ -0,0 +1,38 @@
+/*
+ * tmc26x.h
+ *
+ * Created: 2/7/2018 10:17:49 PM
+ *  Author: Jake
+ */ 
+
+
+#ifndef TMC26X_H_
+#define TMC26X_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;
+}tmc26_t;
+
+void tmc26_init(tmc26_t *tmc, spiport_t *spi, pin_t *en, pin_t *sg);
+
+void tmc26_write(tmc26_t *tmc, uint32_t word);
+
+void tmc26_start(tmc26_t *tmc);
+
+void tmc26_update(tmc26_t *tmc);
+
+void tmc26_enable(tmc26_t *tmc);
+
+void tmc26_disable(tmc26_t *tmc);
+
+#endif /* TMC2660_H_ */
\ No newline at end of file
diff --git a/embedded/atkstepper17/atkstepper17/uartport.c b/embedded/atkstepper17/atkstepper17/uartport.c
new file mode 100644
index 0000000000000000000000000000000000000000..8b51d63cb10a34774577d7b82e0f7937fcecd41e
--- /dev/null
+++ b/embedded/atkstepper17/atkstepper17/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/atkstepper17/atkstepper17/uartport.h b/embedded/atkstepper17/atkstepper17/uartport.h
new file mode 100644
index 0000000000000000000000000000000000000000..72fa539b121a11546dddae9a76892d4ad2ef0315
--- /dev/null
+++ b/embedded/atkstepper17/atkstepper17/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
diff --git a/embedded/atkstepper23/atkstepper23/atkhandler.c b/embedded/atkstepper23/atkstepper23/atkhandler.c
index 85c6ce94cb50ff4269c876a03a4de57071a2d6c1..b0decb920d6defc5f52df04eba9136cca660028b 100644
--- a/embedded/atkstepper23/atkstepper23/atkhandler.c
+++ b/embedded/atkstepper23/atkstepper23/atkhandler.c
@@ -30,6 +30,7 @@ void atk_handle_packet(uint8_t *packet, uint8_t length){
 			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 ++;
@@ -59,6 +60,17 @@ void atk_handle_packet(uint8_t *packet, uint8_t length){
 							stepper_new_block(packet, &stepper, steps, entryspeed, accel, accellength, deccellength);
 						}
 						break;
+					
+					case DELIM_KEY_WAIT:
+						if(i + 8 > length){
+							i ++;
+						} else {
+							steps = ((int32_t)packet[i+1] << 24) | ((int32_t)packet[i+2] << 16) | ((int32_t)packet[i+3] << 8) | (int32_t)packet[i+4];
+							// in steps/s
+							uint32_t speed = ((int32_t)packet[i+5] << 24) | ((int32_t)packet[i+6] << 16) | ((int32_t)packet[i+7] << 8) | (int32_t)packet[i+8];
+							i += 8;
+							stepper_new_wait(packet, &stepper, steps, speed);
+						}
 											
 					default:
 						// probably an error
diff --git a/embedded/atkstepper23/atkstepper23/atkhandler.h b/embedded/atkstepper23/atkstepper23/atkhandler.h
index d676f9a5740f698671fd9ce71379ad2f7f834d68..1b6879aa507d2433667ff90eda849c58a8c25f65 100644
--- a/embedded/atkstepper23/atkstepper23/atkhandler.h
+++ b/embedded/atkstepper23/atkstepper23/atkhandler.h
@@ -18,6 +18,7 @@
 #define DELIM_KEY_RESET 128 
 
 #define DELIM_KEY_TRAPEZOID 131 
+#define DELIM_KEY_WAIT 132
 
 void atk_handle_packet(uint8_t *packet, uint8_t length);
 
diff --git a/embedded/atkstepper23/atkstepper23/main.c b/embedded/atkstepper23/atkstepper23/main.c
index 52521e26e4f6ec45c329568dac92a9b9f29e57f8..cf19332b78d02d7c9cfe076ba5ea374db194079c 100644
--- a/embedded/atkstepper23/atkstepper23/main.c
+++ b/embedded/atkstepper23/atkstepper23/main.c
@@ -129,8 +129,8 @@ int main(void)
  		tck++;
  		// this modulo op is slow AF
  		// that means streamlining atkport_scan without modulos is probably a rad thing
-    	if(!(fastModulo(tck, 16384))){
-     		//pin_toggle(&stlclk);
+    	if(!(fastModulo(tck, 4096))){
+     		pin_toggle(&stlclk);
      	}
 	}
 }
diff --git a/embedded/atkstepper23/atkstepper23/stepper.c b/embedded/atkstepper23/atkstepper23/stepper.c
index 656ab0b1f1f353e53e198506133c620b9b493e74..8fb78ee0e1bb7ecd35673bbbb1f610a61311a80b 100644
--- a/embedded/atkstepper23/atkstepper23/stepper.c
+++ b/embedded/atkstepper23/atkstepper23/stepper.c
@@ -45,84 +45,94 @@ void stepper_new_block(uint8_t *packet, stepper_t *stepper, int32_t steps, uint3
 		stepper->block[stepper->blockhead].packet[i] = packet[i];
 	}
 	
-	if(entryspeed == 0){
-		// 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
-		(accel < 3) ? accel = 3 : (0);
-		(accel > 187500) ? accel = 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 = accel;
-		stepper->block[stepper->blockhead].position_end = abs(steps);
-		stepper->block[stepper->blockhead].accel_period = STEPTICKER_ONE_SECOND;
-		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){
-			// could we just call stepper_update now?
-			uint16_t newper = STEPTICKER_ONE_SECOND / accel;
-			stepticker_newperiod(newper);
-			stepticker_reset();
-			uint16_t accper = 65536; // gets 16-bit truncated
-			accelticker_newperiod(accper);
-			accelticker_reset();
-		}
+	// 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 {
-		// 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();
-		}
+		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){
@@ -171,14 +181,13 @@ void stepper_updatesteps(stepper_t *stepper){
 		// apa_return_packet(stepper->block[stepper->blocktail].packet, 25);
 		uint8_t reply[2];
 		if(stepper->block[stepper->blocktail].is_nomove){
-			reply[0] = 131;
+			reply[0] = DELIM_KEY_WAIT;
 			reply[1] = 12;
 			} else {
-			reply[0] = 131;
+			reply[0] = DELIM_KEY_TRAPEZOID;
 			reply[1] = 24;
 		}
 		atk_reply_packet(stepper->block[stepper->blocktail].packet, reply, 2);
-		
 		// 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
@@ -189,23 +198,23 @@ 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;
+		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;
+		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;
+		(0);
+		break;
 		default:
-			(0);
-			break;
+		(0);
+		break;
 	}
 }
 
diff --git a/embedded/atkstepper23/atkstepper23/stepper.h b/embedded/atkstepper23/atkstepper23/stepper.h
index 562f8c39d17d34f75db74975763e02a53c334adf..e58e77cb6114d131f10cb6536b210d20e440b617 100644
--- a/embedded/atkstepper23/atkstepper23/stepper.h
+++ b/embedded/atkstepper23/atkstepper23/stepper.h
@@ -72,6 +72,8 @@ 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);