diff --git a/embedded/README.md b/embedded/README.md
index 45fc919af907b6395ee8fb1b3d38a5538dff8031..f6becb033ad4e7c09bac5adc379509b3bd9247a2 100644
--- a/embedded/README.md
+++ b/embedded/README.md
@@ -314,7 +314,7 @@ SPI commands and responses are all 20-bits long. Each 20-bit command is met with
 
 Most likely, operation will consist of starting up with sending all 5 registers sequentially in the setup config, and then occasionally polling one to get the response (which, it looks like, contains useful things like relative loads!). 
 
-Late on, when I try to make a closed loop stepper with the AS5147, I'll be writing coil currents directly into these registers (I think?) to commutate the motor based on encoder input and a tiny PID loop. That, later - but for now I see that in the DRVCTRL register has two 8-bit words for Current in A and Current in B. Noice.
+Later on, when I try to make a closed loop stepper with the AS5147, I'll be writing coil currents directly into these registers (I think?) to commutate the motor based on encoder input and a tiny PID loop. That, later - but for now I see that in the DRVCTRL register has two 8-bit words for Current in A and Current in B. Noice.
 
 Another thing I like is that I can set both step edges to signify a step. Normally, step drivers have a 'minimum on time' and only count the positive edge, so the microcode has to do a tiny wait (normally not long enough to warrant an interrupt-to-turn-off). This way I'll just toggle the step pin whenever I want to step, and I can forget about it.
 
@@ -330,4 +330,133 @@ Great, now we unfux the hacked together code, and try to send some data, then so
 
 I think I'm actually going to try writing this library from the datasheet. Let's see how that goes.
 
-Er, how about we just write some values down manually and send those? Sounds good.
\ No newline at end of file
+OK, great news. This morning Will and Sam reminded me that I can just write binary with the prefix '0b' and GCC will make bits out of that. How wonderful. Here's my TMC setup:
+
+```C
+/*
+ * tmc2660.c
+ *
+ * Created: 2/7/2018 10:17:39 PM
+ *  Author: Jake
+ */ 
+
+#include "tmc2660.h"
+
+tmc2260_t tmc2660_new(spiport_t *spi, pin_t *step, pin_t *dir, pin_t *en, pin_t *sg){
+	tmc2260_t tmc;
+	
+	tmc.spi = spi;
+	tmc.step_pin = step;
+	tmc.dir_pin = dir;
+	tmc.en_pin = en;
+	tmc.sg_pin = sg;
+	
+	return tmc;
+}
+
+void tmc2660_write(tmc2260_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 tmc2660_init(tmc2260_t *tmc){
+	// 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.305mv, readback stallguard2 data, reserved
+	uint32_t drvconf = 0b11100000000000010000; 
+	tmc2660_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 = 12;
+	uint32_t sgcsconf = 0b11010000000000000000 | ((sgthres_val << 8) & sgthresh_mask) | (cscale_val & cscale_mask);
+	tmc2660_write(tmc, sgcsconf);
+	
+	// turning coolstep off
+	uint32_t smarten = 0b10100000000000000000;
+	tmc2660_write(tmc, smarten);
+	
+	// times, delays, cycle mode
+	uint32_t chopconf = 0b10010010100000010111;
+	tmc2660_write(tmc, chopconf);
+	
+	// 9th bit is intpol, 8th is dedge, last 4 are microstepping
+	uint32_t drvctrl = 0b00000000000100000001;
+	tmc2660_write(tmc, drvctrl);
+}
+
+
+void tmc2660_update(tmc2260_t *tmc){
+	uint32_t smarten = 0b10100000000000000000;
+	tmc2660_write(tmc, smarten);
+}
+```
+
+Here's a capture from the logic analyzer, from boot. I write 5 addresses with the settings above (init) and then I'm polling the driver periodically for stallguard data, by just re-writing a register (I'm re-writing the smarten register, because it's disabled and so I feel safer about not accidentally changing anything). 
+
+![spi](https://gitlab.cba.mit.edu/jakeread/mkstepper/raw/master/images/spi-tmc-fromboot.png)
+
+It took me a minute to figure out how to properly align the 20-bit word within three 8-bit bytes that the SPI peripheral on the ATSAMD51 can handle. There's also a 32 bit extension, which it might make sense to write to, instead. ~ or ~ use a buffer and txinterrupt to fire the series of bytes away. At the moment, I'm polling that flag (txready) before each new byte, meaning when I send a register the processor is waiting around until they're all on the line, and this is non-ideal. However, I was able to push the SPI speed up to 6.25MBPS, so the wait is only 5us (for one register). That's OK. 
+
+![spi](https://gitlab.cba.mit.edu/jakeread/mkstepper/raw/master/images/spi-tmc-speed.png)
+
+I'm running at 0.8A current and everything is nice and cool. When I drive this up to 1.9A, things start to heat up. Next time I draw the board I can likely do a bit better at dissipating heat - a bit helpful step would be to bring the copper thickness past 1oz, that way I can comfortably drive NEMA23s. What would be cooler (haha) would be a little bit of implementation on the coolStep feature, which intelligently sets current in a closed-loop manner, while watching the stallGuard setting - that all happens in the TMC.
+
+The driver's not dead silent, but I expect if I were to play with the settings it might get better. It's certainly better than most drivers I've used. 
+
+# Step Timing
+
+In any case! Towards making these kits of parts do CNC things, I want to be able to send commands to this board like "go x steps at y speed" - with a buffer of these commands, I should be able to successfully sync network steppers in a motion control application. There will of course be the tricky problem of synchronization (!) and to be honest I don't have a good plan for that yet.
+
+Pending success today on 'x steps at y speed' - or maybe better is to do 'x steps over y time' - same thing really, but the latter logic probably better for whatever is upstream, breaking motion into discrete chunks of time before networking them - I can spend some time tomorrow at drafting that architecture.
+
+OK, so. Lit review. AKA asking Sam, Will, and looking at other step-motion-controller softwares online. I'm familiar with Smoothie and Marlin.
+
+I believe most people do this with timers or 'tickers' that run around 1kHz to periodically check and step-or-not-step based on elapsed time, steps left, etc. First thing would be to write a quick table to check how often I'll have to do this in order to reliably step at certain speeds, with this gnarly 128 or 256 microstepping in the TMC. 
+
+Looks like this needs to be pretty fast. In retrospect, that 1kHz ticker I was thinking about was running an acceleration update loop. The actual step ticker has to be much faster ... for 200RPM (which does about 190mm/s on an 18mm diameter pulley) while driving 64 microsteps (more than enough) we have a 43kHz tick. So I'll be writing a ~ 10us ticker, I think. Not unreasonable in microcontroller land. 
+
+## Planning
+
+What's the rest of the plan? I'll need a timer, for sure. I want to run that on the real-time clock and use the kHz crystal I put on the board for that. 
+
+Let's see - there's kind of a lot of different ways to do this. Basically, we are just changing position at set time. Forgive me for getting undergraduate here. My intuition is to make this really simple: we track position, and tell each motor to go to positions at certain times. On the next level up, we do acceleration planning. This would require sending messages across the network at around 1kHz, probably more. 
+
+Maybe a better way is for each block to have an 'end of block' speed and position - and the motors are responsible for ramping up or down over the course of a segment. Then we set two timers: one to check steps to be made against a speed, one to check if the speed needs to be updated. But I'll need to do some head-scratching to figure how to make all of those ends meet: get here at this time and be doing this speed at the end. Feels over-constrained. 
+
+Actually I think this is ideal, on the D-t chart I'm sending commands to get to a point with the curve having a particular slope at that point. I'm drawing bezier type curves that inform a point-to-point S-t chart:
+
+![ptst-naive](https://gitlab.cba.mit.edu/jakeread/mkstepper/raw/master/images/wb-ptst-naive.jpg)
+
+Or is this naive? It is: the S-t points integrate into the P-t points, so by adding the tangent to the P-t information I'm over-constraining the solution for S-t. However, I should be able to decouple those things in whatever planning-level maths I'm doing, and reliably send 'ramp linear to be at this speed at this time' - trouble is that then I'm in time-series, and have to count on the last steps integrating properly into position. Hmmmm. 
+
+So if I send the over-constrained information, I can let the stepper motor error correct by adding some juice of its own, or taking some away, over the time of the block:
+
+![ptst-integrate](https://gitlab.cba.mit.edu/jakeread/mkstepper/raw/master/images/wb-ptst-integrate.jpg)
+
+So we end up doing error correction on the 3rd order for acceleration on the 2nd order. Sounds like I might be making this into a more-complicated-than-it-need-be exercise. Rather than trying to add that next bezier, juts do this: add a point, midpoint to current S-t plan, such that the integral matches. Low cpu overhead, good little error correction, still get to feel secure about positioning, while maintaining the ability to do networked acceleration without flooding hella position messages. 
+
+![ptst-integrate](https://gitlab.cba.mit.edu/jakeread/mkstepper/raw/master/images/wb-ptst-integrate-simple.jpg)
+
+I can check for bounds: like that mid-point (or any combination thereof) driving the acceleration past some max, or I can just count on the controller one level up being a benevolent / brilliant overlord, and go for gold no matter the circumstance. 
+
+Cornering, etc, is actually kind of interesting. See [this note on 'junction deviation'](https://onehossshay.wordpress.com/2011/09/24/improving_grbl_cornering_algorithm/) from the Grbl squad. 
+
+So, here's the plan:
+ - get command (although this was a nice discussion, to implement with speed I'm going to take the input 'go, for this speed, for this duration' first)
+ - update parameters for loops: current speed (defining an integral to check against) and block start time.
+ - build a fast realtime timer to run both of these things,
+ - one interrupt updates the time value, an overflowing 32bit integer?
+ - one interrupt runs the ticker, checking:
+  - do we need to make a step? if yes, do, and update position
+  - is the block over? ok.
+
+OK, ENOUGH CHAT amirite? Let's get down to bones and write a timer.
+
+Er, first I'm going to wrap these C bits up nicely and commit. 
\ No newline at end of file
diff --git a/embedded/mkstepper-v011/mkstepper-v011/hardware.h b/embedded/mkstepper-v011/mkstepper-v011/hardware.h
index 7d369f2ae65c2c1d12704a1c079bb0bb746d8a96..60974c4fb729d3eae8cf976d2ff4a1b1a0f61757 100644
--- a/embedded/mkstepper-v011/mkstepper-v011/hardware.h
+++ b/embedded/mkstepper-v011/mkstepper-v011/hardware.h
@@ -33,6 +33,6 @@ pin_t dir_pin;
 pin_t en_pin;
 pin_t sg_pin;
 
-tmc2260_t tmc;
+tmc26_t tmc;
 
 #endif /* HARDWARE_H_ */
\ No newline at end of file
diff --git a/embedded/mkstepper-v011/mkstepper-v011/main.c b/embedded/mkstepper-v011/mkstepper-v011/main.c
index 6e4553574414df6005e1d68164738cf072904471..194b8c4cb4b58df7acb523881cfe6b8bfd85ccde 100644
--- a/embedded/mkstepper-v011/mkstepper-v011/main.c
+++ b/embedded/mkstepper-v011/mkstepper-v011/main.c
@@ -115,7 +115,6 @@ int main(void)
 	MCLK->APBDMASK.reg |= MCLK_APBDMASK_SERCOM5;
 	uart_init(&up2, 7, SERCOM5_GCLK_ID_CORE, 63018);
 	
-	
 	// SPI
 	// TMC_MOSI		PA07 / SER0-3
 	// TMC_MISO		PA04 / SER0-0
@@ -125,7 +124,7 @@ int main(void)
 	// spi
 	spi_tmc = spi_new(SERCOM0, &PORT->Group[0], 4, 7, 5, 6, HARDWARE_IS_APBA, HARDWARE_ON_PERIPHERAL_D);
 	MCLK->APBAMASK.reg |= MCLK_APBAMASK_SERCOM0;
-	spi_init(&spi_tmc, 8, SERCOM0_GCLK_ID_CORE, 126, 0, 2, 0, 0, 1, 0);
+	spi_init(&spi_tmc, 8, SERCOM0_GCLK_ID_CORE, 3, 0, 2, 0, 1, 1, 0);
 	
 	// TMC
 	// STEP			PB08
@@ -133,22 +132,32 @@ int main(void)
 	// EN			PB07
 	// SG			PB06
 	
-	step_pin = pin_new(&PORT->Group[1], 8);
-	dir_pin = pin_new(&PORT->Group[1], 9);
 	en_pin = pin_new(&PORT->Group[1], 7);
 	sg_pin = pin_new(&PORT->Group[1], 6);
 	
-	tmc = tmc2660_new(&spi_tmc, &step_pin, &dir_pin, &en_pin, &sg_pin);
-	tmc2660_init(&tmc);
+	tmc = tmc26_new(&spi_tmc, &en_pin, &sg_pin);
+	// set registers
+	tmc26_init(&tmc);
+	// enable
+	tmc26_enable(&tmc);
+	
+	step_pin = pin_new(&PORT->Group[1], 8);
+	dir_pin = pin_new(&PORT->Group[1], 9);
+	pin_output(&step_pin);
+	pin_output(&dir_pin);
 			
     while (1) 
     {
-		tmc2660_init(&tmc);
+		//pin_clear(&en_pin);
+		tmc26_update(&tmc);
+		//pin_set(&en_pin);
+		//pin_toggle(&step_pin);
 		// delay
-		for(int i=0; i < 500; i++){
+		for(int i=0; i < 12; i++){
 			pin_toggle(&stlr);
 		}
-		// find TMC registers now, try to read!
+		// step
+		pin_toggle(&step_pin);
 		
     }
 }
diff --git a/embedded/mkstepper-v011/mkstepper-v011/spiport.c b/embedded/mkstepper-v011/mkstepper-v011/spiport.c
index a291180c545e9da0050870125a457b844b669cd6..974bbb00297276d1de1b0a1e843befdc5bb220bf 100644
--- a/embedded/mkstepper-v011/mkstepper-v011/spiport.c
+++ b/embedded/mkstepper-v011/mkstepper-v011/spiport.c
@@ -112,7 +112,7 @@ void spi_txchar_polled(spiport_t *spi, uint8_t data){
 void spi_txchars_polled(spiport_t *spi, uint8_t *data, uint8_t length){
 	spi->port->OUTCLR.reg = spi->csn_bm;
 	for(int i = 0; i < length; i ++){
-		spi_txchar_polled(spi, data[0]);
+		spi_txchar_polled(spi, data[i]);
 	}
 	while(!spi->com->SPI.INTFLAG.bit.TXC); // wait for complete before
 	spi->port->OUTSET.reg = spi->csn_bm;
diff --git a/embedded/mkstepper-v011/mkstepper-v011/tmc26.c b/embedded/mkstepper-v011/mkstepper-v011/tmc26.c
new file mode 100644
index 0000000000000000000000000000000000000000..ff770d25628971a2faa3c25492421f04a561cf90
--- /dev/null
+++ b/embedded/mkstepper-v011/mkstepper-v011/tmc26.c
@@ -0,0 +1,70 @@
+/*
+ * tmc2660.c
+ *
+ * Created: 2/7/2018 10:17:39 PM
+ *  Author: Jake
+ */ 
+
+#include "tmc2660.h"
+
+tmc26_t tmc26_new(spiport_t *spi, pin_t *en, pin_t *sg){
+	tmc26_t tmc;
+	
+	tmc.spi = spi;
+	tmc.en_pin = en;
+	tmc.sg_pin = sg;
+	
+	return tmc;
+}
+
+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_init(tmc26_t *tmc){
+	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.305mv, readback stallguard2 data, reserved
+	uint32_t drvconf = 0b11100000000000010000; 
+	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 = 12;
+	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 = 0b10010010100000010111;
+	tmc26_write(tmc, chopconf);
+	
+	// 9th bit is intpol, 8th is dedge, last 4 are microstepping
+	uint32_t drvctrl = 0b00000000000100000010;
+	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_set(tmc->en_pin);
+}
+
+tmc26_disable(tmc26_t *tmc){
+	pin_clear(tmc->en_pin);
+}
\ No newline at end of file
diff --git a/embedded/mkstepper-v011/mkstepper-v011/tmc2660.h b/embedded/mkstepper-v011/mkstepper-v011/tmc26.h
similarity index 54%
rename from embedded/mkstepper-v011/mkstepper-v011/tmc2660.h
rename to embedded/mkstepper-v011/mkstepper-v011/tmc26.h
index 0025e10c66ea2e5192957959dac0f129456b4e7a..8ff49cbbef503fe78cd86dc1869081d137e58af7 100644
--- a/embedded/mkstepper-v011/mkstepper-v011/tmc2660.h
+++ b/embedded/mkstepper-v011/mkstepper-v011/tmc26.h
@@ -21,12 +21,18 @@ typedef struct{
 	pin_t *en_pin;
 	
 	pin_t *sg_pin;
-}tmc2260_t;
+}tmc26_t;
 
-tmc2260_t tmc2660_new(spiport_t *spi, pin_t *step, pin_t *dir, pin_t *en, pin_t *sg);
+tmc26_t tmc26_new(spiport_t *spi, pin_t *en, pin_t *sg);
 
-void tmc2660_init(tmc2260_t *tmc);
+void tmc26_write(tmc26_t *tmc, uint32_t word);
 
-void tmc2660_step_once(tmc2260_t *tmc, uint8_t dir);
+void tmc26_init(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/mkstepper-v011/mkstepper-v011/tmc2660.c b/embedded/mkstepper-v011/mkstepper-v011/tmc2660.c
deleted file mode 100644
index 5a883f02a1eb32f721e91ca0c9b99ea2530283f5..0000000000000000000000000000000000000000
--- a/embedded/mkstepper-v011/mkstepper-v011/tmc2660.c
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * tmc2660.c
- *
- * Created: 2/7/2018 10:17:39 PM
- *  Author: Jake
- */ 
-
-#include "tmc2660.h"
-
-tmc2260_t tmc2660_new(spiport_t *spi, pin_t *step, pin_t *dir, pin_t *en, pin_t *sg){
-	tmc2260_t tmc;
-	
-	tmc.spi = spi;
-	tmc.step_pin = step;
-	tmc.dir_pin = dir;
-	tmc.en_pin = en;
-	tmc.sg_pin = sg;
-	
-	return tmc;
-}
-
-void tmc2660_init(tmc2260_t *tmc){
-	// lots
-	// pins are also init externally
-	// spi is init externally, godbless
-	uint8_t data[3] = {8, 9, 10};
-	spi_txchars_polled(tmc->spi, data, 3);
-}
-
diff --git a/images/spi-tmc-fromboot.png b/images/spi-tmc-fromboot.png
new file mode 100644
index 0000000000000000000000000000000000000000..87c7b401c5dcec0a9524097fd71a3cf87e42c05d
Binary files /dev/null and b/images/spi-tmc-fromboot.png differ
diff --git a/images/spi-tmc-speed.png b/images/spi-tmc-speed.png
new file mode 100644
index 0000000000000000000000000000000000000000..5145f1acbfb54c8145261c63090a0b43dc044dcc
Binary files /dev/null and b/images/spi-tmc-speed.png differ
diff --git a/images/wb-ptst-integrate-simple.jpg b/images/wb-ptst-integrate-simple.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..e24cd9bbacc141d19059ac60b5912136038d913c
Binary files /dev/null and b/images/wb-ptst-integrate-simple.jpg differ
diff --git a/images/wb-ptst-integrate.jpg b/images/wb-ptst-integrate.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..a86be8b885858a22ae4ad1281d23d6877861135a
Binary files /dev/null and b/images/wb-ptst-integrate.jpg differ
diff --git a/images/wb-ptst-naive.jpg b/images/wb-ptst-naive.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..6397361f4243ad2321468185d1ceb96b94f9fda9
Binary files /dev/null and b/images/wb-ptst-naive.jpg differ