From 4d34a3398daa5ede4819f998ae142eba99d0958f Mon Sep 17 00:00:00 2001
From: Jake Read <jake.read@cba.mit.edu>
Date: Mon, 10 Jan 2022 22:54:57 -0500
Subject: [PATCH] microstep

---
 firmware/fab-step/src/drivers/step_a4950.cpp | 53 +++++++++++++++-----
 firmware/fab-step/src/drivers/step_a4950.h   |  9 ++++
 firmware/fab-step/src/main.cpp               | 17 ++-----
 log/fab-step-log.md                          | 27 +++++++---
 4 files changed, 72 insertions(+), 34 deletions(-)

diff --git a/firmware/fab-step/src/drivers/step_a4950.cpp b/firmware/fab-step/src/drivers/step_a4950.cpp
index 8dde6b9..5106cee 100644
--- a/firmware/fab-step/src/drivers/step_a4950.cpp
+++ b/firmware/fab-step/src/drivers/step_a4950.cpp
@@ -16,6 +16,9 @@ is; no warranty is provided, and users accept all liability.
 #include "../indicators.h"
 
 // LUT, 0-1022, 64 entries, sin w/ 511 at midpoint 
+// full sweep of electrical phase is actually 4 'steps' - 
+// so making a full step means incrementing 16 times through this LUT, 
+// half step is 8, quarter step 4, eighth step 2, sixteenth microstepping is one, fin 
 uint16_t LUT_1022[64] = {
     511,561,611,659,707,752,795,835,872,906,936,962,983,1000,1012,1020,
     1022,1020,1012,1000,983,962,936,906,872,835,795,752,707,659,611,561,
@@ -104,24 +107,50 @@ void step_a4950_set_cscale(float scale){
     step_a4950_publish_currents();
 }
 
+// step states
+boolean _dir = true;                            // current direction 
+boolean _dirInvert = false;                     // invert directions ?
+uint8_t _microstep_count = MICROSTEP_16_COUNT;  // default to 16th microstepping 
+uint8_t lutptra = 16;                           // current pt. in microstep phase 
+uint8_t lutptrb = 0;                            // A leads B by 1/4 period 
+
 void step_a4950_set_microstep(uint8_t microstep){
-    // 
+    switch(microstep){
+        case 64:
+            _microstep_count = MICROSTEP_64_COUNT;
+            break;
+        case 32:
+            _microstep_count = MICROSTEP_32_COUNT;
+            break;
+        case 16:
+            _microstep_count = MICROSTEP_16_COUNT;
+            break;
+        case 8:
+            _microstep_count = MICROSTEP_8_COUNT;
+            break;
+        case 4: 
+            _microstep_count = MICROSTEP_4_COUNT;
+            break;
+        case 2:
+            _microstep_count = MICROSTEP_2_COUNT;
+            break;
+        case 1:
+            _microstep_count = MICROSTEP_1_COUNT;
+            break;
+        default:
+            _microstep_count = MICROSTEP_1_COUNT;
+            break;
+    }
 }
 
-// step states
-boolean _dir = true;        // current direction 
-boolean _dirInvert = false; // invert directions ?
-uint8_t lutptra = 16;        // current pt. in microstep phase 
-uint8_t lutptrb = 0;       // A leads B by 1/4 period 
-
 void step_a4950_step(){
-    // step LUT ptrs thru table, 
+    // step LUT ptrs thru table, increment and wrap w/ bit logic 
     if(_dir){
-        lutptra ++; if(lutptra >= 64) lutptra = 0;
-        lutptrb ++; if(lutptrb >= 64) lutptrb = 0;
+        lutptra += _microstep_count; lutptra = lutptra & 0b00111111;
+        lutptrb += _microstep_count; lutptrb = lutptrb & 0b00111111;
     } else {
-        (lutptra == 0) ? lutptra = 63 : lutptra --;
-        (lutptrb == 0) ? lutptrb = 63 : lutptrb --;
+        lutptra -= _microstep_count; lutptra = lutptra & 0b00111111;
+        lutptrb -= _microstep_count; lutptrb = lutptrb & 0b00111111;
     }
     // depending on sign of phase, set up / down on gates 
     if(LUT_1022[lutptra] > 511){
diff --git a/firmware/fab-step/src/drivers/step_a4950.h b/firmware/fab-step/src/drivers/step_a4950.h
index 2e57475..ae4da2c 100644
--- a/firmware/fab-step/src/drivers/step_a4950.h
+++ b/firmware/fab-step/src/drivers/step_a4950.h
@@ -17,6 +17,15 @@ is; no warranty is provided, and users accept all liability.
 
 #include <Arduino.h> 
 
+// lol 
+#define MICROSTEP_64_COUNT 1
+#define MICROSTEP_32_COUNT 1
+#define MICROSTEP_16_COUNT 1
+#define MICROSTEP_8_COUNT 2 
+#define MICROSTEP_4_COUNT 4
+#define MICROSTEP_2_COUNT 8
+#define MICROSTEP_1_COUNT 16 
+
 // AIN1 PA14
 // AIN2 PA15 
 // BIN1 PA05 
diff --git a/firmware/fab-step/src/main.cpp b/firmware/fab-step/src/main.cpp
index a2ab555..70f62e0 100644
--- a/firmware/fab-step/src/main.cpp
+++ b/firmware/fab-step/src/main.cpp
@@ -44,15 +44,6 @@ EP_ONDATA_RESPONSES onMicrostepData(uint8_t* data, uint16_t len){
 
 endpoint_t* microstepEp = osapBuildEndpoint("microstep", onMicrostepData);
 
-// -------------------------------------------------------- SPU EP
-
-EP_ONDATA_RESPONSES onSPUData(uint8_t* data, uint16_t len){
-  // doesn't do anything w/ step-on-tick situation 
-  return EP_ONDATA_ACCEPT;
-}
-
-endpoint_t* spuEp = osapBuildEndpoint("SPU", onSPUData, nullptr);
-
 // -------------------------------------------------------- CSCALE DATA
 
 EP_ONDATA_RESPONSES onCScaleData(uint8_t* data, uint16_t len){
@@ -117,13 +108,11 @@ void setup() {
   osapAddEndpoint(axisInvertEp);    // 3
   // microstep 
   osapAddEndpoint(microstepEp);     // 4
-  // SPU 
-  osapAddEndpoint(spuEp);           // 5
   // cscale 
-  osapAddEndpoint(cScaleEp);        // 6
+  osapAddEndpoint(cScaleEp);        // 5
   // homing 
-  osapAddEndpoint(homeEp);          // 7 
-  osapAddEndpoint(homeStateEp);     // 8 
+  osapAddEndpoint(homeEp);          // 6 
+  osapAddEndpoint(homeStateEp);     // 7 
   // step hardware init 
   step_a4950_init();
 }
diff --git a/log/fab-step-log.md b/log/fab-step-log.md
index df4fc87..232345f 100644
--- a/log/fab-step-log.md
+++ b/log/fab-step-log.md
@@ -314,15 +314,26 @@ Now I just want to touch up the motor APIs in JS, and add the steps-per-unit adj
 
 ### Power State API 
 
-- do need this, and it needs to be part of the 'setup' routine 
+Just a bunch of buttons, turns out to not be so bad. Done. 
 
 ### New Motor API and JS Config 
 
-- check that 'microstep' config does what it claims (?) 
-- now ... we need to reconsider how / whomst makes SPU / dir configs, etc 
-    - inversion is per-motor 
-    - so is microstepping 
-    - so is the axis pick 
-    - spu is per-axis in the head 
+This should actually be chill... it's working after all, right? 
 
-A final treat would be reconfiguring the ucbus-stepper firmware to match this. Another treat would be a tiny demo video for Donny. 
\ No newline at end of file
+I'm setting the SPUs in the motion-head now... meaning I could also calculate / guard against max rates there. 
+
+- motion-head things 
+    - steps per unit 
+    - max accels 
+    - max rates 
+- motor things 
+    - direction inversion 
+    - microstepping 
+    - axis picking 
+
+OK I've diffed all that... need to make a microstep update actually do something, then this adventure is over. 
+
+11752 / 24584 
+12520 / 24976
+
+Done, for the time being. Probably needs in-mcu guards against large rates. 
\ No newline at end of file
-- 
GitLab