diff --git a/firmware/cl-step-controller/src/drivers/step_cl.cpp b/firmware/cl-step-controller/src/drivers/step_cl.cpp
index 1569014e5228ee92b94db5842d1deeb10c867fc2..383c1edaf7aa6a4aca576027566a4667e484842f 100644
--- a/firmware/cl-step-controller/src/drivers/step_cl.cpp
+++ b/firmware/cl-step-controller/src/drivers/step_cl.cpp
@@ -92,7 +92,7 @@ void flash_write_value(float val){
 
 void Step_CL::print_table(void){
     sysError("reading from lut");
-    for(uint32_t i = 0; i < ENCODER_COUNTS * 2; i ++){
+    for(uint32_t i = 0; i < ENCODER_COUNTS; i ++){
         float ra = lut[i * 2];
         float pa = lut[i * 2 + 1];
         sysError("real angle at enc " + String(i) + ": " + String(ra) + "phase angle: " + String(pa));
@@ -123,23 +123,23 @@ void Step_CL::run_torque_loop(void){
 
 #define MAP_7p2_TO_1 (1.0F / 7.2F)
 #define TICKS_PER_SEC 50000.0F
+#define SECS_PER_TICK 1.0F / TICKS_PER_SEC
 volatile float _ra;
 volatile float _ra_last;
-volatile float _ra_s; // real angle / sec 
+volatile float _deg_s; // real angle / sec 
 volatile float _pa;
 
+float Step_CL::get_deg_sec(void){
+    return _deg_s;
+}
+
 void ENC_AS5047::on_read_complete(uint16_t result){
     if(step_cl->is_calibrating) return;
     _ra = lut[result * 2];          // the real angle (position 0-360)
     _pa = lut[result * 2 + 1];      // the phase angle (0 - 1 in a sweep of 4 steps)
     // want to calculate speeds, 
-    //here 
-    // need to calculate speed but in context of wrap'd angle: is there a quick way?
-    // then test with scope
-    // then do JS running some loop, maybe 1khz possible? *awk face* send cmd effort down, retrieve datas 
-    // probably just will want to retrieve speed ... then see about sweeping the field to build your table, 
-    // then next step would be real calib against something known ? 
-    _ra_s = (_ra - _ra_last) / TICKS_PER_SEC;
+    // just this is not going to be good enough: have to wrap that angle 
+    _deg_s = (_ra - _ra_last) * TICKS_PER_SEC;
     _ra_last = _ra; // upd8 for next tick 
     // this is the phase angle we want to apply, 90 degs off & wrap't to 1 
     if(step_cl->get_torque() < 0){
diff --git a/firmware/cl-step-controller/src/drivers/step_cl.h b/firmware/cl-step-controller/src/drivers/step_cl.h
index 902353b0b7847dfe93096df4f0069843545a9a92..1343da1663fdcf51e5e38b9758861187c8696878 100644
--- a/firmware/cl-step-controller/src/drivers/step_cl.h
+++ b/firmware/cl-step-controller/src/drivers/step_cl.h
@@ -33,6 +33,7 @@ class Step_CL {
         void print_table(void);
         void set_torque(float tc);
         float get_torque(void);
+        float get_deg_sec(void);
         void run_torque_loop(void);
         boolean calibrate(void);
         boolean is_calibrating;
diff --git a/firmware/cl-step-controller/src/main.cpp b/firmware/cl-step-controller/src/main.cpp
index 121c3c6f29f4064bd0314863e931567ecc632595..10954416692b66e0f506189181f8ef1021468231 100644
--- a/firmware/cl-step-controller/src/main.cpp
+++ b/firmware/cl-step-controller/src/main.cpp
@@ -175,6 +175,8 @@ void OSAP::handleAppPacket(uint8_t *pck, uint16_t pl, uint16_t ptr, uint16_t seg
         reply[rl ++] = AK_SET_TC;
         chunk_float32 tcs = { .bytes = { pck[ptr ++], pck[ptr ++], pck[ptr ++], pck[ptr ++] }};
         step_cl->set_torque(tcs.f);
+        float deg_sec = step_cl->get_deg_sec();
+        ts_writeFloat32(deg_sec, reply, &rl);
         break;
       }
     default:
diff --git a/log/2020-10-17_a4950-decay-time.png b/log/2020-10-17_a4950-decay-time.png
new file mode 100644
index 0000000000000000000000000000000000000000..2618ce5a1c38ee29a06a2689641b40dacdbded0c
Binary files /dev/null and b/log/2020-10-17_a4950-decay-time.png differ
diff --git a/log/cl-step-control-log.md b/log/cl-step-control-log.md
index 5866df8ada158874aea894a8319647284dae93b3..152c08d12e62041b968c607317900a4263497021 100644
--- a/log/cl-step-control-log.md
+++ b/log/cl-step-control-log.md
@@ -1063,7 +1063,65 @@ So the first move is to build in to the lower level a velocity measurement. For
 
 What's a reasonable 'end spiral' for this?
 
-- do phase advance parameter, 
+I do want to get to phase advance today & the beginnings of the JS 'looping' interface: that will determine if I need to build better underlaying architecture before continuing... py serial, or rpi node->uart. 
+
+### Phase Advance 
+
+So let's see... I want to know about angular velocity's relation to RPM / relation to angular phases / second. 
+
+```
+1 rpm = 6 deg/s
+7.2 deg/s = 1 magnetic phase / sec
+```
+
+So there is a nice kind of parity here, 
+
+```
+1 rpm = 0.83 magnetic phase / sec 
+``` 
+
+Supposing that the stator 'points' immediately at the end of each loop, I'll have one speed limit related to the angular travel in between each loop: if I set my phase 90deg ahead at the end of one loop, but the rotor is moving more than 90deg (magnetic: 1.8 physical) per loop period, I'm in trouble. This limit actually seems quite high: it's about 15krpm. 
+
+| rpm | deg/s | mag phases / sec | us / mag phase | us / quarter mag phase |
+| --- | --- | --- | --- | --- | 
+| 15000 | 90000 | 12500 | 80 | 20 |
+| 10000 | 60000 | 8333 | 120 | 30 |
+
+This doesn't mean that's *absolute max* speed, it's just a crossing point where I would be applying some negative torque during part of the rotation if I went any faster.
+
+Since optimal torque is applied at 90* out of phase with the current rotor position, to do this ideally I would set the magnetic vector of the stator ahead of 90* by 1/2 of the phase angle covered by the rotor during the loop time, so that, during the rotation taking place during this period of the loop, the effective angle would average to 90*.  
+
+Of course, I'm not pointing my magnetic vector *immediately* when I write the DACs - indeed, even the chopper drive in the A4950s has a 25us fixed off time during current decay, about half of my loop cycle time. 
+
+![chopper](2020-10-17_a4950-decay-time.png) 
+
+Besides this, there's the actual rise time of the coils: the real magnetic lag. This means that in reality, I'll want to set my phase advance well ahead of the *ideal* 90 deg, to compensate for slower parts of the system. 
+
+Were I a bit more intrepid, I could do things like measure phase inductance, etc, and could probably figure pretty well exactly how far ahead it were reasonable to set the phase advance. However! In reality, this is probably a tuned variable: and one that is probably not hard to search for. 
+
+### Roughing It 
+
+That said! I want to set it and forget about it for now: I can come back here if I ever want to chase some more gains. I showed up here just trying to ballpark a first guess. Basically, I think I should set my phase advance at 90deg when rpm = 0, and then scale it to a maximum of 180deg when things are going quite fast: based on my control-loop-speed guessing above (where the abs max before crossover was 15krpm) and based on my intuitive knowledge that I am unlikely to spin this stepper faster than 10krpm, I'll set the top there. 
+
+```
+where 0.5 == 180 degs of phase advance 
+phase advance = 0.25 + min(0.25, deg/s * 0.000004)
+```
+
+This is a kind of crazy small floating point, and I besides need to calculate my speed - which, really, I should do some filtering there because I know there's a few ticks of error in the encoder. 
+
+### Speed Maths 
+
+Discrete deeeeeerivatiiiives 
+
+I think this is probably not hard, however, doing it fast is maybe more challenging. I also need to set up some infrastructure I think to do it well: this js looping situation. Maybe that first. 
+
+- phase advance can be 'roughly' to do 0.25 + min(speed * x, 0.25) where x is set such that speed * x goes to 0.25 around 2000rpm (by intuition) but really I should make a spreadsheet to figure where (if current writing is direct) the pole-rotation time starts to sync with the 50khz, you know what I mean?
+- also read ur datasheets abt current chopping time ? 
+- in the end, phase advance probably just tuned 
+- do manuel-set phase advance parameter, 
 - do js interface for tc down, degs/sec up, plot on loop 
 - see about sweeping parameter space, learning real torque
-- measure against real values, from, what? 
\ No newline at end of file
+- measure against real values, from, what? 
+- to learn PID, command PID params down, return accumulated error over set evaluation period, do learning over sample gcodes ? means integration into bus, etc 
+- seems likely that PID learning is related to acceleration setting in smoothie, maybe somehow do multiple accel vals? also return w/ pid an average effort used, and a maximum? ideally tunes motor PID, and per-axis accel all together 
\ No newline at end of file