diff --git a/2020-06_ucbus-stepper-melted/2020-06_ucbus-stepper-melted.sch b/2020-06_ucbus-stepper-melted/2020-06_ucbus-stepper-melted.sch
index f281a26c5b65de80dbc83b3c1e5d97ca053ef98e..9ef117fbf15f06d974bddde426de270e198431e3 100644
--- a/2020-06_ucbus-stepper-melted/2020-06_ucbus-stepper-melted.sch
+++ b/2020-06_ucbus-stepper-melted/2020-06_ucbus-stepper-melted.sch
@@ -6,36 +6,36 @@
 <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"/>
+<grid distance="0.1" unitdist="inch" unit="inch" style="lines" multiple="1" display="no" altdistance="0.01" altunitdist="inch" altunit="inch"/>
 <layers>
-<layer number="1" name="Top" color="4" fill="1" visible="yes" active="no"/>
-<layer number="2" name="Route2" color="16" fill="1" visible="yes" active="no"/>
-<layer number="3" name="Route3" color="17" fill="1" visible="yes" active="no"/>
-<layer number="4" name="Route4" color="18" fill="1" visible="yes" active="no"/>
-<layer number="5" name="Route5" color="19" fill="1" visible="yes" active="no"/>
-<layer number="6" name="Route6" color="25" fill="1" visible="yes" active="no"/>
-<layer number="7" name="Route7" color="26" fill="1" visible="yes" active="no"/>
-<layer number="8" name="Route8" color="27" fill="1" visible="yes" active="no"/>
-<layer number="9" name="Route9" color="28" fill="1" visible="yes" active="no"/>
-<layer number="10" name="Route10" color="29" fill="1" visible="yes" active="no"/>
-<layer number="11" name="Route11" color="30" fill="1" visible="yes" active="no"/>
-<layer number="12" name="Route12" color="20" fill="1" visible="yes" active="no"/>
-<layer number="13" name="Route13" color="21" fill="1" visible="yes" active="no"/>
-<layer number="14" name="Route14" color="22" fill="1" visible="yes" active="no"/>
-<layer number="15" name="Route15" color="23" fill="1" visible="yes" active="no"/>
-<layer number="16" name="Bottom" color="1" fill="1" visible="yes" active="no"/>
-<layer number="17" name="Pads" color="2" fill="1" visible="yes" active="no"/>
-<layer number="18" name="Vias" color="2" fill="1" visible="yes" active="no"/>
-<layer number="19" name="Unrouted" color="6" fill="1" visible="yes" active="no"/>
-<layer number="20" name="Dimension" color="24" fill="1" visible="yes" active="no"/>
-<layer number="21" name="tPlace" color="7" fill="1" visible="yes" active="no"/>
-<layer number="22" name="bPlace" color="7" fill="1" visible="yes" active="no"/>
-<layer number="23" name="tOrigins" color="15" fill="1" visible="yes" active="no"/>
-<layer number="24" name="bOrigins" color="15" fill="1" visible="yes" active="no"/>
-<layer number="25" name="tNames" color="7" fill="1" visible="yes" active="no"/>
-<layer number="26" name="bNames" color="7" fill="1" visible="yes" active="no"/>
-<layer number="27" name="tValues" color="7" fill="1" visible="yes" active="no"/>
-<layer number="28" name="bValues" color="7" fill="1" visible="yes" active="no"/>
+<layer number="1" name="Top" color="4" fill="1" visible="no" active="no"/>
+<layer number="2" name="Route2" color="16" fill="1" visible="no" active="no"/>
+<layer number="3" name="Route3" color="17" fill="1" visible="no" active="no"/>
+<layer number="4" name="Route4" color="18" fill="1" visible="no" active="no"/>
+<layer number="5" name="Route5" color="19" fill="1" visible="no" active="no"/>
+<layer number="6" name="Route6" color="25" fill="1" visible="no" active="no"/>
+<layer number="7" name="Route7" color="26" fill="1" visible="no" active="no"/>
+<layer number="8" name="Route8" color="27" fill="1" visible="no" active="no"/>
+<layer number="9" name="Route9" color="28" fill="1" visible="no" active="no"/>
+<layer number="10" name="Route10" color="29" fill="1" visible="no" active="no"/>
+<layer number="11" name="Route11" color="30" fill="1" visible="no" active="no"/>
+<layer number="12" name="Route12" color="20" fill="1" visible="no" active="no"/>
+<layer number="13" name="Route13" color="21" fill="1" visible="no" active="no"/>
+<layer number="14" name="Route14" color="22" fill="1" visible="no" active="no"/>
+<layer number="15" name="Route15" color="23" fill="1" visible="no" active="no"/>
+<layer number="16" name="Bottom" color="1" fill="1" visible="no" active="no"/>
+<layer number="17" name="Pads" color="2" fill="1" visible="no" active="no"/>
+<layer number="18" name="Vias" color="2" fill="1" visible="no" active="no"/>
+<layer number="19" name="Unrouted" color="6" fill="1" visible="no" active="no"/>
+<layer number="20" name="Dimension" color="24" fill="1" visible="no" active="no"/>
+<layer number="21" name="tPlace" color="7" fill="1" visible="no" active="no"/>
+<layer number="22" name="bPlace" color="7" fill="1" visible="no" active="no"/>
+<layer number="23" name="tOrigins" color="15" fill="1" visible="no" active="no"/>
+<layer number="24" name="bOrigins" color="15" fill="1" visible="no" active="no"/>
+<layer number="25" name="tNames" color="7" fill="1" visible="no" active="no"/>
+<layer number="26" name="bNames" color="7" fill="1" visible="no" active="no"/>
+<layer number="27" name="tValues" color="7" fill="1" visible="no" active="no"/>
+<layer number="28" name="bValues" color="7" fill="1" visible="no" active="no"/>
 <layer number="29" name="tStop" color="7" fill="3" visible="no" active="no"/>
 <layer number="30" name="bStop" color="7" fill="6" visible="no" active="no"/>
 <layer number="31" name="tCream" color="7" fill="4" visible="no" active="no"/>
@@ -44,8 +44,8 @@
 <layer number="34" name="bFinish" color="6" fill="6" visible="no" active="no"/>
 <layer number="35" name="tGlue" color="7" fill="4" visible="no" active="no"/>
 <layer number="36" name="bGlue" color="7" fill="5" visible="no" active="no"/>
-<layer number="37" name="tTest" color="7" fill="1" visible="yes" active="no"/>
-<layer number="38" name="bTest" color="7" fill="1" visible="yes" active="no"/>
+<layer number="37" name="tTest" color="7" fill="1" visible="no" active="no"/>
+<layer number="38" name="bTest" color="7" fill="1" visible="no" active="no"/>
 <layer number="39" name="tKeepout" color="4" fill="11" visible="no" active="no"/>
 <layer number="40" name="bKeepout" color="1" fill="11" visible="no" active="no"/>
 <layer number="41" name="tRestrict" color="4" fill="10" visible="no" active="no"/>
@@ -53,19 +53,19 @@
 <layer number="43" name="vRestrict" color="2" fill="10" visible="no" active="no"/>
 <layer number="44" name="Drills" color="7" fill="1" visible="no" active="no"/>
 <layer number="45" name="Holes" color="7" fill="1" visible="no" active="no"/>
-<layer number="46" name="Milling" color="3" fill="1" visible="yes" active="no"/>
-<layer number="47" name="Measures" color="7" fill="1" visible="yes" active="no"/>
-<layer number="48" name="Document" color="7" fill="1" visible="yes" active="no"/>
-<layer number="49" name="Reference" color="7" fill="1" visible="yes" active="no"/>
-<layer number="50" name="dxf" color="7" fill="1" visible="yes" active="no"/>
-<layer number="51" name="tDocu" color="7" fill="1" visible="yes" active="no"/>
-<layer number="52" name="bDocu" color="7" fill="1" visible="yes" active="no"/>
-<layer number="53" name="tGND_GNDA" color="7" fill="9" visible="yes" active="no"/>
-<layer number="54" name="bGND_GNDA" color="1" fill="9" visible="yes" active="no"/>
-<layer number="56" name="wert" color="7" fill="1" visible="yes" active="no"/>
-<layer number="57" name="tCAD" color="7" fill="1" visible="yes" active="no"/>
-<layer number="59" name="tCarbon" color="7" fill="1" visible="yes" active="no"/>
-<layer number="60" name="bCarbon" color="7" fill="1" visible="yes" active="no"/>
+<layer number="46" name="Milling" color="3" fill="1" visible="no" active="no"/>
+<layer number="47" name="Measures" color="7" fill="1" visible="no" active="no"/>
+<layer number="48" name="Document" color="7" fill="1" visible="no" active="no"/>
+<layer number="49" name="Reference" color="7" fill="1" visible="no" active="no"/>
+<layer number="50" name="dxf" color="7" fill="1" visible="no" active="no"/>
+<layer number="51" name="tDocu" color="7" fill="1" visible="no" active="no"/>
+<layer number="52" name="bDocu" color="7" fill="1" visible="no" active="no"/>
+<layer number="53" name="tGND_GNDA" color="7" fill="9" visible="no" active="no"/>
+<layer number="54" name="bGND_GNDA" color="1" fill="9" visible="no" active="no"/>
+<layer number="56" name="wert" color="7" fill="1" visible="no" active="no"/>
+<layer number="57" name="tCAD" color="7" fill="1" visible="no" active="no"/>
+<layer number="59" name="tCarbon" color="7" fill="1" visible="no" active="no"/>
+<layer number="60" name="bCarbon" color="7" fill="1" visible="no" active="no"/>
 <layer number="88" name="SimResults" color="9" fill="1" visible="yes" active="yes"/>
 <layer number="89" name="SimProbes" color="9" fill="1" visible="yes" active="yes"/>
 <layer number="90" name="Modules" color="5" fill="1" visible="yes" active="yes"/>
diff --git a/2020-06_ucbus-stepper-melted/eagle.epf b/2020-06_ucbus-stepper-melted/eagle.epf
index c6124db219e541ad483c9ef381af95bc7b36e378..40d2f7e9ba6cc0385badb035e12aa6690666cd10 100644
--- a/2020-06_ucbus-stepper-melted/eagle.epf
+++ b/2020-06_ucbus-stepper-melted/eagle.epf
@@ -283,9 +283,9 @@ UsedLibrary="C:/Dropbox/CBA/circuits/eagle/parts/usbraw.lbr"
 
 [Win_1]
 Type="Schematic Editor"
-Number=1
-File="C:/dropbox/cba/advisory/bhutan/2021-09-14_lora/2021-07-20_loRA-jake.sch"
-View="32.1497 9.16998 132.794 77.8767"
+Number=2
+File="2020-06_ucbus-stepper-melted.sch"
+View="-12.0464 -0.366016 451.466 255.354"
 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"
@@ -324,21 +324,20 @@ ArcDirection=0
 AddLevel=2
 PadsSameType=0
 Layer=91
-Views=" 1: 32.1497 9.16998 132.794 77.8767"
 Sheet="1"
 
 [Win_2]
 Type="Board Editor"
-Number=2
-File="C:/dropbox/cba/advisory/bhutan/2021-09-14_lora/2021-07-20_loRA-jake.brd"
-View="12.7615 -1.4366 44.9353 36.7389"
-WireWidths=" 0.8 0.9 0.1 0.05 0.5 0 0.3 0.2032 0.1524"
+Number=1
+File="2020-06_ucbus-stepper-melted.brd"
+View="20.9387 29.9114 29.2137 38.6903"
+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.9 1 0.6 0.85"
+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"
 ViaDiameters=" 0.55 0.6 0.65 0.7 0.75 0.8 0.85 0.9 0.95 1 1.05 1.1 1.15 1.2 1.3 0"
-ViaDrills=" 0.2 0.25 0.45 0.5 0.55 0.6 0.65 0.7 0.75 0.8 0.9 1 0.35 0.4 0.3 0.85"
-HoleDrills=" 0.2 0.25 0.3 0.4 0.45 0.5 0.55 0.6 0.65 0.7 0.75 0.8 0.9 1 0.35 0.85"
-TextSizes=" 0.254 0.3048 0.4064 0.6096 0.8128 1.27 1.4224 1.6764 1.9304 2.1844 2.54 3.81 5.08 6.4516 1.778 1.016"
+ViaDrills=" 0.2 0.25 0.3 0.4 0.45 0.5 0.55 0.6 0.65 0.7 0.75 0.8 0.85 0.9 1 0.35"
+HoleDrills=" 0.2 0.25 0.3 0.4 0.45 0.5 0.55 0.6 0.65 0.7 0.75 0.8 0.85 0.9 1 0.35"
+TextSizes=" 0.254 0.3048 0.4064 0.6096 0.8128 1.016 1.27 1.4224 1.6764 1.9304 2.1844 2.54 3.81 5.08 6.4516 1.778"
 PolygonSpacings=" 0.254 0.3048 0.4064 0.6096 0.8128 1.016 1.4224 1.6764 1.778 1.9304 2.1844 2.54 3.81 5.08 6.4516 1.27"
 PolygonIsolates=" 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"
 MiterRadiuss=" 0.254 0.3175 0.635 1.27 2.54 1 2 2.5 5 7.5 10 0"
@@ -354,7 +353,7 @@ MiterStyle=1
 PadShape=0
 ViaShape=1
 PolygonPour=0
-PolygonRank=4
+PolygonRank=1
 PolygonThermals=1
 PolygonOrphans=0
 TextRatio=8
@@ -369,14 +368,14 @@ SwapLevel=0
 ArcDirection=0
 AddLevel=2
 PadsSameType=0
-Layer=1
+Layer=16
 
 [Win_3]
 Type="Control Panel"
 Number=0
 
 [Desktop]
-Screen="3171 2520"
+Screen="1920 1080"
 Window="Win_1"
 Window="Win_2"
 Window="Win_3"
diff --git a/firmware/stepper-drop/src/drivers/step_a4950.h b/firmware/stepper-drop/src/drivers/step_a4950.h
index fc435d3ba208ca92e42264a4e682722db21aa934..1f6e606cab5ca31783fc188452a15a4826f7deac 100644
--- a/firmware/stepper-drop/src/drivers/step_a4950.h
+++ b/firmware/stepper-drop/src/drivers/step_a4950.h
@@ -33,7 +33,8 @@ is; no warranty is provided, and users accept all liability.
 // 4:   16 microsteps
 // 8:   8 microsteps
 // 16:  4 microsteps
-// 32:  full steps 
+// 32:  2 microsteps (half steps)
+// 64:  full steps 
 #define MICROSTEP_COUNT 1
 
 #define MICROSTEP_64_COUNT 1
@@ -41,7 +42,8 @@ is; no warranty is provided, and users accept all liability.
 #define MICROSTEP_16_COUNT 4
 #define MICROSTEP_8_COUNT 8 
 #define MICROSTEP_4_COUNT 16
-#define MICROSTEP_1_COUNT 32 
+#define MICROSTEP_2_COUNT 32
+#define MICROSTEP_1_COUNT 64 
 
 // AIN1 PB06
 // AIN2 PA04 
diff --git a/firmware/stepper-drop/src/homing.cpp b/firmware/stepper-drop/src/homing.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..a2b782c86fe8d8876c7cffb517d420b12f802b6a
--- /dev/null
+++ b/firmware/stepper-drop/src/homing.cpp
@@ -0,0 +1,92 @@
+/*
+homing.cpp
+
+tiny homing routine for fab-step 
+
+Jake Read at the Center for Bits and Atoms
+(c) Massachusetts Institute of Technology 2022
+
+This work may be reproduced, modified, distributed, performed, and
+displayed for any purpose, but must acknowledge the OSAP project. 
+Copyright is retained and must be preserved. The work is provided as
+is; no warranty is provided, and users accept all liability.
+*/
+
+#include "homing.h"
+#include "drivers/step_a4950.h"
+
+endpoint_t* _homeStateEP;
+uint8_t homeState = HOMESTATE_NONE;
+uint32_t homeBackoffStepsTaken = 0;
+
+// home settings 
+boolean homeDir = true;
+unsigned long lastHomeOperation = 0;
+unsigned long homeOperationPeriod = 1000; // in us 
+uint32_t homeBackoffDistance = 100;
+
+void homeSetup(endpoint_t* homeStateEP){
+    // stash this 
+    _homeStateEP = homeStateEP;
+    // make an input 
+    PORT->Group[LIMIT_PORT].DIRCLR.reg = (1 << LIMIT_PIN);
+    PORT->Group[LIMIT_PORT].PINCFG[LIMIT_PIN].bit.INEN = 1;
+    // pullup 
+    PORT->Group[LIMIT_PORT].OUTSET.reg = (1 << LIMIT_PIN);
+}
+
+// return true if limit switch is hit 
+boolean limitHit(void){
+    return (PORT->Group[LIMIT_PORT].IN.reg & (1 << LIMIT_PIN));
+}
+
+void writeHomeSettings(boolean dir, uint32_t stepsPerSecond, uint32_t offset){
+    homeDir = dir;
+    homeOperationPeriod = 1000000 / stepsPerSecond;
+    homeBackoffDistance = offset;
+}
+
+uint8_t getHomeState(void){
+    return homeState;
+}
+
+void startHomingRoutine(void){
+    homeState = HOMESTATE_APPROACH;
+    endpointWrite(_homeStateEP, &homeState, 1);
+}
+
+void runHomingRoutine(void){
+  // run this at a rate... 
+  if(lastHomeOperation + homeOperationPeriod > micros()) return;
+  lastHomeOperation = micros();
+  // state switch; 
+  switch(homeState){
+    case HOMESTATE_NONE:
+      break;
+    case HOMESTATE_APPROACH: 
+      // check for contact, 
+      if(limitHit()){
+        homeState = HOMESTATE_BACKOFF;
+        endpointWrite(_homeStateEP, &homeState, 1);
+        homeBackoffStepsTaken = 0;
+      } else {
+        stepper_hw->dir(homeDir);
+        stepper_hw->step();
+      }
+      break;
+    case HOMESTATE_BACKOFF:
+      stepper_hw->dir(!homeDir);
+      stepper_hw->step();
+      homeBackoffStepsTaken ++;
+      if(homeBackoffStepsTaken > homeBackoffDistance){
+        homeState = HOMESTATE_NONE;
+        endpointWrite(_homeStateEP, &homeState, 1);
+      }
+      break;
+    default:
+      // broken, 
+      homeState = HOMESTATE_NONE;
+      endpointWrite(_homeStateEP, &homeState, 1);
+      break;
+  }
+}
\ No newline at end of file
diff --git a/firmware/stepper-drop/src/homing.h b/firmware/stepper-drop/src/homing.h
new file mode 100644
index 0000000000000000000000000000000000000000..e0249bd30cb62f14a28986215e77b6151894b31b
--- /dev/null
+++ b/firmware/stepper-drop/src/homing.h
@@ -0,0 +1,37 @@
+/*
+homing.h
+
+tiny homing routine 
+
+Jake Read at the Center for Bits and Atoms
+(c) Massachusetts Institute of Technology 2022
+
+This work may be reproduced, modified, distributed, performed, and
+displayed for any purpose, but must acknowledge the OSAP project. 
+Copyright is retained and must be preserved. The work is provided as
+is; no warranty is provided, and users accept all liability.
+*/
+
+#ifndef HOMING_H_ 
+#define HOMING_H_ 
+
+#include <Arduino.h>
+#include "osape-d51/osape/osap/endpoint.h"
+
+// limit 
+#define LIMIT_PORT 0 
+#define LIMIT_PIN 23
+
+// home states
+#define HOMESTATE_NONE 0
+#define HOMESTATE_APPROACH 1
+#define HOMESTATE_BACKOFF 2
+
+void homeSetup(endpoint_t* homeStateEP);
+boolean limitHit(void);
+uint8_t getHomeState(void);
+void writeHomeSettings(boolean dir, uint32_t stepsPerSecond, uint32_t offset);
+void startHomingRoutine(void);
+void runHomingRoutine(void);
+
+#endif 
\ No newline at end of file
diff --git a/firmware/stepper-drop/src/main.cpp b/firmware/stepper-drop/src/main.cpp
index 64702eaf66d4968cd251de8ba5ef1b92f5c21dec..be9ee3b389b11858951ec66070d85f889d9f6679 100644
--- a/firmware/stepper-drop/src/main.cpp
+++ b/firmware/stepper-drop/src/main.cpp
@@ -2,45 +2,37 @@
 
 #include "indicators.h"
 #include "drivers/step_a4950.h"
+#include "homing.h"
 #include "osape-d51/osape/osap/osap.h"
 #include "osape-d51/vertices/vt_usbSerial.h"
 #include "osape-d51/vertices/ucbus/vt_ucBusDrop.h"
 #include "osape-d51/vertices/ucbus/ucBusDrop.h"
 
 // bare defaults: use vm / bus id to set on startup 
-uint8_t axis_pick = 0;
-float spu = 400.0F;
-float old_spu = 400.0F;
-volatile boolean spu_was_set = false;
-float c_scale = 0.00F;
-#define TICKS_PER_PACKET 25.0F
-#define TICKS_PER_SECOND 50000.0F
+uint8_t axisPick = 0;
+boolean invert = false;
 
 // -------------------------------------------------------- AXIS PICK EP 
 
 EP_ONDATA_RESPONSES onAxisPickData(uint8_t* data, uint16_t len){
   if(data[0] > 3){
-    axis_pick = 0;
+    axisPick = 0;
   } else {
-    axis_pick = data[0];
+    axisPick = data[0];
   }
   return EP_ONDATA_ACCEPT;
 }
 
-vertex_t* axisPickEp = osapBuildEndpoint("axisPick", onAxisPickData, nullptr);
+endpoint_t* axisPickEp = osapBuildEndpoint("axisPick", onAxisPickData);
 
 // -------------------------------------------------------- AXIS INVERSION EP
 
 EP_ONDATA_RESPONSES onAxisInvertData(uint8_t* data, uint16_t len){
-  if(data[0] > 0){
-    stepper_hw->setInversion(true);
-  } else {
-    stepper_hw->setInversion(false);
-  }
+  data[0] ? invert = true : invert = false;
   return EP_ONDATA_ACCEPT;
 }
 
-vertex_t* axisInvertEp = osapBuildEndpoint("axisInvert", onAxisInvertData, nullptr);
+endpoint_t* axisInvertEp = osapBuildEndpoint("axisInvert", onAxisInvertData);
 
 // -------------------------------------------------------- MICROSTEP EP 
 
@@ -49,19 +41,7 @@ EP_ONDATA_RESPONSES onMicrostepData(uint8_t* data, uint16_t len){
   return EP_ONDATA_ACCEPT;
 }
 
-vertex_t* microstepEp = osapBuildEndpoint("microstep", onMicrostepData, nullptr);
-
-// -------------------------------------------------------- SPU EP
-
-EP_ONDATA_RESPONSES onSPUData(uint8_t* data, uint16_t len){
-  chunk_float32 spuc = { .bytes = { data[0], data[1], data[2], data[3] } };
-  old_spu = spu;
-  spu = fabsf(spuc.f);
-  spu_was_set = true;
-  return EP_ONDATA_ACCEPT;
-}
-
-vertex_t* spuEp = osapBuildEndpoint("SPU", onSPUData, nullptr);
+endpoint_t* microstepEp = osapBuildEndpoint("microstep", onMicrostepData);
 
 // -------------------------------------------------------- CSCALE DATA
 
@@ -76,262 +56,102 @@ EP_ONDATA_RESPONSES onCScaleData(uint8_t* data, uint16_t len){
   return EP_ONDATA_ACCEPT;
 }
 
-vertex_t* cScaleEp = osapBuildEndpoint("CScale", onCScaleData, nullptr);
+endpoint_t* cScaleEp = osapBuildEndpoint("CScale", onCScaleData);
 
-// -------------------------------------------------------- HOME ROUTINE
-
-// some homeing globals, 
-#define HOME_NOT 0
-#define HOME_FIRST 1
-#define HOME_BACKOFF 2
-
-uint8_t homing = 0;           // statemachine 
-float homeStepCounter = 0.0F; // step-float-counter
-float homePos = 0.0F;         // position (units)
-float homeStepRate = 0.0F;    // rate (steps/tick)
-float homePosRate = 0.0F;     // rate (units/tick)
-boolean homeDir = false;      // direction 
-float homeOffset = 0.0F;      // after-home offset 
+// -------------------------------------------------------- HOME ROUTINE 
 
 EP_ONDATA_RESPONSES onHomeData(uint8_t* data, uint16_t len){
-  chunk_float32 rate = { .bytes = { data[0], data[1], data[2], data[3] } };
-  chunk_float32 offset = { .bytes = { data[4], data[5], data[6], data[7] } };
-  homing = HOME_FIRST;
-  homeStepCounter = 0.0F;
-  if(rate.f > 0){
-    homeDir = true;
-    stepper_hw->dir(true);
+  chunk_int32 rate = { .bytes = { data[0], data[1], data[2], data[3] } };
+  chunk_uint32 offset = { .bytes = { data[4], data[5], data[6], data[7] } };
+  // sign of rate is dir, 
+  boolean hdir;
+  uint32_t hrate;
+  if(rate.i < 0) {
+    hdir = false;
+    hrate = -1 * rate.i;
   } else {
-    homeDir = false;
-    stepper_hw->dir(false);
+    hdir = true;
+    hrate = rate.i;
   }
-  homeStepRate = abs(rate.f * spu) / TICKS_PER_SECOND;
-  homePosRate = abs(rate.f) / TICKS_PER_SECOND;
-  homeOffset = offset.f;
+  writeHomeSettings(hdir, hrate, offset.u);
+  startHomingRoutine();
   return EP_ONDATA_ACCEPT;
 }
 
-vertex_t* homeEp = osapBuildEndpoint("Home", onHomeData, nullptr);
+endpoint_t* homeEp = osapBuildEndpoint("Home", onHomeData);
 
 // -------------------------------------------------------- HOME STATE 
 
-boolean beforeHomeStateQuery(void);
-
-vertex_t* homeStateEp = osapBuildEndpoint("HomeState", nullptr, beforeHomeStateQuery);
-
-boolean beforeHomeStateQuery(void){
-  homeStateEp->ep->data[0] = homing;
-  homeStateEp->ep->dataLen = 1;
-  return true;
-}
-
-// -------------------------------------------------------- LIMIT SETUP 
+endpoint_t* homeStateEp = osapBuildEndpoint("HomeState");
 
-#define LIMIT_PORT PORT->Group[0]
-#define LIMIT_PIN 23 
-#define LIMIT_BM ((uint32_t)(1 << LIMIT_PIN))
-
-void limitSetup(void){
-  // not-an-output 
-  LIMIT_PORT.DIRCLR.reg = LIMIT_BM;
-  // enable input 
-  LIMIT_PORT.PINCFG[LIMIT_PIN].bit.INEN = 1;
-  // enable pull 
-  LIMIT_PORT.PINCFG[LIMIT_PIN].bit.PULLEN = 1;
-  // 'pull' references direction from 'out' register, so we set hi to pull up (switch pulls to gnd)
-  LIMIT_PORT.OUTSET.reg = LIMIT_BM;
-}
-
-boolean limitIsMade(void){
-  // return true if switch is hit 
-  return (LIMIT_PORT.IN.reg & LIMIT_BM);
-}
+// -------------------------------------------------------- SETUP 
 
 void setup() {
   ERRLIGHT_SETUP;
   CLKLIGHT_SETUP;
-  DEBUG1PIN_SETUP;
-  // limit switch 
-  //limitSetup();
+  //DEBUG1PIN_SETUP;
+  homeSetup(homeStateEp);
   // osap
-  osapSetup();
+  osapSetup("ucbus-stepper");
   // ports 
   vt_usbSerial_setup();
   osapAddVertex(vt_usbSerial);    // 0
   vt_ucBusDrop_setup(true, 0);
   osapAddVertex(vt_ucBusDrop);    // 1
   // axis pick 
-  osapAddVertex(axisPickEp);      // 2
+  osapAddEndpoint(axisPickEp);      // 2
   // axis invert
-  osapAddVertex(axisInvertEp);    // 3
+  osapAddEndpoint(axisInvertEp);    // 3
   // microstep 
-  osapAddVertex(microstepEp);     // 4
-  // SPU 
-  osapAddVertex(spuEp);           // 5
+  osapAddEndpoint(microstepEp);     // 4
   // cscale 
-  osapAddVertex(cScaleEp);        // 6
+  osapAddEndpoint(cScaleEp);        // 5
   // homing 
-  osapAddVertex(homeEp);          // 7 
-  osapAddVertex(homeStateEp);     // 8 
+  osapAddEndpoint(homeEp);          // 6 
+  osapAddEndpoint(homeStateEp);     // 7 
   // stepper init 
-  stepper_hw->init(false, c_scale);
+  stepper_hw->init(false, 0.0F);
 }
 
-uint8_t testRx[256];
+// -------------------------------------------------------- LOOP 
 
 void loop() {
   osapLoop();
   stepper_hw->dacRefresh();
-  // still not sure: this registers as "made" on init (?) 
-  if(limitIsMade()){
-    ERRLIGHT_ON;
-  } else {
-    ERRLIGHT_OFF;
-  }
+  limitHit() ? ERRLIGHT_ON : ERRLIGHT_OFF;
+  // home statemachine 
+  if(getHomeState() != HOMESTATE_NONE) runHomingRoutine();
 } // end loop 
 
+// -------------------------------------------------------- BUS INTERRUPT / STEP 
 
-volatile float current_floating_pos = 0.0F;
-volatile int32_t current_step_pos = 0;
-volatile uint32_t delta_steps = 0;
-
-volatile float vel = 0.0F; 
-volatile float move_counter = 0.0F;
-
-volatile boolean setBlock = false;
+uint8_t stepCache[2];
+volatile uint8_t cachePtr = 0;
+volatile boolean stepValid = false;
+volatile uint8_t stepMask = 0;
 
 void ucBusDrop_onPacketARx(uint8_t* inBufferA, volatile uint16_t len){
-  // don't execute when we have been given a set-position block 
-  if(setBlock) return;
-  // don't execute if we are currently homing
-  if(homing) return;
-  //DEBUG2PIN_TOGGLE;
-  // last move is done, convert back steps -> float,
-  if(spu_was_set){
-    current_floating_pos = current_step_pos / old_spu;
-    current_step_pos = lroundf(current_floating_pos * spu);
-    spu_was_set = false;
-  } else {
-    current_floating_pos = current_step_pos / spu;
-  }
-  vel = 0.0F; // reset zero in case packet is not move 
-  uint8_t bptr = 0;
-  // switch bus packet types 
-  switch(inBufferA[0]){
-    case UB_AK_GOTOPOS:
-      {
-        bptr = axis_pick * 4 + 1;
-        chunk_float32 target = {
-          .bytes = { inBufferA[bptr], inBufferA[bptr + 1], inBufferA[bptr + 2], inBufferA[bptr + 3] }
-        };
-        /*
-        chunk_float64 target = { 
-          .bytes = { inBuffer[bptr], inBuffer[bptr + 1], inBuffer[bptr + 2], inBuffer[bptr + 3],
-                    inBuffer[bptr + 4], inBuffer[bptr + 5], inBuffer[bptr + 6], inBuffer[bptr + 7] }};
-                    */
-        float delta = target.f - current_floating_pos;
-        // update,
-        //move_counter = 0.0F; // shouldn't need this ? try deleting 
-        // direction swop,
-        if(delta > 0){
-          stepper_hw->dir(true);
-        } else {
-          stepper_hw->dir(false);
-        }
-        // how many steps, 
-        delta_steps = lroundf(abs(delta * spu));
-        // what speed 
-        vel = abs(delta * spu) / TICKS_PER_PACKET;
-        // for str8 r8 
-        /*
-        if(delta_steps == 0){
-          vel = 0.0F;
-        } else {
-          vel = abs(delta * SPU) / TICKS_PER_PACKET;
-        }
-        */
-        break; // end gotopos 
-      }
-    case UB_AK_SETPOS:
-      {
-        // reqest is to set position, not go to it... 
-        bptr = axis_pick * 4 + 1;
-        chunk_float32 target = {
-          .bytes = { inBufferA[bptr], inBufferA[bptr + 1], inBufferA[bptr + 2], inBufferA[bptr + 3] }
-        };
-        float target_current_pos = target.f;
-        int32_t target_current_steps = lroundf(target_current_pos * spu);
-        setBlock = true; // don't do step work while these are modified 
-        current_floating_pos = target_current_pos;
-        current_step_pos = target_current_steps;
-        vel = 0;
-        delta_steps = 0;
-        setBlock = false;
-        break;
-      }
-    default:
-      break;
-  }  
-  //DEBUG2PIN_OFF;
+  // refill step cache:
+  stepCache[0] = inBufferA[0]; stepCache[1] = inBufferA[1];
+  cachePtr = 0;
+  stepValid = true;
 }
 
 void ucBusDrop_onRxISR(void){
-  // no-op when given a set block, 
-  if(setBlock) return;
-  // incremental motion if is homing 
-  if(homing != 0){
-    switch(homing){
-      case HOME_FIRST:
-        if(limitIsMade()){
-          // traaaaaaansition -> backoff 
-          stepper_hw->dir(!homeDir);
-          homeStepCounter = 0.0F;
-          homePos = 0.0F;
-          homing = HOME_BACKOFF;
-        } else {
-          homeStepCounter += homeStepRate;
-          if(homeStepCounter >= 1.0F){
-            homeStepCounter -= 1.0F;
-            stepper_hw->step();
-          }
-        }
-        break;
-      case HOME_BACKOFF:
-        homeStepCounter += homeStepRate;
-        homePos += homePosRate;
-        if(homeStepCounter >= 1.0F){  // backoff motion 
-          homeStepCounter -= 1.0F;
-          stepper_hw->step();
-        }
-        if(homePos >= homeOffset){ // until more than 2mm away 
-          // traaaaaaaaaaaaaansition -> end 
-          homing = 0;
-        }
-        break;
-      default:
-        homing = 0;
-    }
-    return;
-  }
-  // normal step operation 
-  //DEBUG2PIN_TOGGLE;
-  move_counter += vel;
-  boolean move_check = (move_counter > 1.0F);
-  //DEBUG2PIN_TOGGLE;
-  if(move_check){
-    move_counter -= 1.0F;
-    if(delta_steps == 0){
-      // nothing 
-    } else {
-      //DEBUG1PIN_TOGGLE;
-      stepper_hw->step();
-      delta_steps --;
-      if(stepper_hw->getDir()){
-        current_step_pos ++;
-      } else {
-        current_step_pos --;
-      }
-    }
+    // if we dont' have valid steps, bail 
+  if(!stepValid) return;
+  // if we're currently homing the motor, bail 
+  if(getHomeState() != HOMESTATE_NONE) return;
+  // extract our step mask
+  stepMask = 0b00000011 & (stepCache[cachePtr] >> (axisPick * 2));
+  // mask -> step api:
+  if(invert){
+    (stepMask & 0b00000001) ? stepper_hw->dir(true) : stepper_hw->dir(false); // dir bit,
+  } else {
+    (stepMask & 0b00000001) ? stepper_hw->dir(false) : stepper_hw->dir(true); // dir bit,
   }
+  if (stepMask & 0b00000010) stepper_hw->step();                           // step bit
+  // increment ptr -> next step mask, if over-wrap, steps no longer valid 
+  cachePtr ++; if(cachePtr >= 2) stepValid = false;
 }
 
diff --git a/firmware/stepper-drop/src/osape-d51 b/firmware/stepper-drop/src/osape-d51
index 23064339e200c3819af8bc55988b57d3eaa28a2e..53c513f461e43ac61d13d0111127b3f174fef466 160000
--- a/firmware/stepper-drop/src/osape-d51
+++ b/firmware/stepper-drop/src/osape-d51
@@ -1 +1 @@
-Subproject commit 23064339e200c3819af8bc55988b57d3eaa28a2e
+Subproject commit 53c513f461e43ac61d13d0111127b3f174fef466