diff --git a/circuit/atkbldcdriver/atkbldcdriver.brd b/circuit/atkbldcdriver/atkbldcdriver.brd
index 0d0bc312f6f55da37359d91c53a2169de053e662..fc5a79f4a7a6a09554cd870ee49b04f7885b9c05 100644
--- a/circuit/atkbldcdriver/atkbldcdriver.brd
+++ b/circuit/atkbldcdriver/atkbldcdriver.brd
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!DOCTYPE eagle SYSTEM "eagle.dtd">
-<eagle version="9.1.1">
+<eagle version="9.0.0">
 <drawing>
 <settings>
 <setting alwaysvectorfont="no"/>
@@ -962,9 +962,6 @@ design rules under a new name.</description>
 <param name="checkRestrict" value="1"/>
 <param name="checkStop" value="0"/>
 <param name="checkValues" value="0"/>
-<param name="checkNames" value="1"/>
-<param name="checkWireStubs" value="1"/>
-<param name="checkPolygonWidth" value="0"/>
 <param name="useDiameter" value="13"/>
 <param name="maxErrors" value="50"/>
 </designrules>
@@ -3641,13 +3638,6 @@ design rules under a new name.</description>
 <wire x1="51.2308" y1="51.1808" x2="50.4" y2="50.35" width="0.1524" layer="1"/>
 </signal>
 </signals>
-<mfgpreviewcolors>
-<mfgpreviewcolor name="soldermaskcolor" color="0xC8008000"/>
-<mfgpreviewcolor name="silkscreencolor" color="0xFFFEFEFE"/>
-<mfgpreviewcolor name="backgroundcolor" color="0xFF282828"/>
-<mfgpreviewcolor name="coppercolor" color="0xFFFFBF00"/>
-<mfgpreviewcolor name="substratecolor" color="0xFF786E46"/>
-</mfgpreviewcolors>
 </board>
 </drawing>
 <compatibility>
diff --git a/circuit/atkbldcdriver/eagle.epf b/circuit/atkbldcdriver/eagle.epf
index 5db0460885a3f79be0605e77e152056e237fe0c6..e04a85b1a1c47aa0d45d630c7e4002ff865ab5a2 100644
--- a/circuit/atkbldcdriver/eagle.epf
+++ b/circuit/atkbldcdriver/eagle.epf
@@ -42,7 +42,7 @@ UsedLibrary="D:/Dropbox (Personal)/CBA/doc/libraries_jake/eagle/sparkfun/SparkFu
 Type="Board Editor"
 Number=1
 File="atkbldcdriver.brd"
-View="46.6255 23.8801 69.1125 42.6084"
+View="41.6112 50.1586 52.4556 59.1904"
 WireWidths=" 0.0762 0.127 0.15 0.508 0.6096 0.8128 2.54 1.016 1.27 0.3048 0.254 0.2 0.4064 0.1016 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.35 0.4 0.45 0.5 0.55 0.65 0.7 0.75 0.8 0.85 0.9 1 0.6 0.3"
@@ -86,7 +86,7 @@ Layer=1
 Type="Schematic Editor"
 Number=3
 File="atkbldcdriver.sch"
-View="-280.35 -76.1712 223.851 152.676"
+View="-250.34 -67.9039 169.828 122.802"
 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"
@@ -125,7 +125,7 @@ ArcDirection=0
 AddLevel=2
 PadsSameType=0
 Layer=91
-Views=" 1: -280.35 -76.1712 223.851 152.676"
+Views=" 1: -250.34 -67.9039 169.828 122.802"
 Sheet="1"
 
 [Win_3]
diff --git a/embedded/README.md b/embedded/README.md
index 7b6fd78b28dcbf8098af889cfaf8dd601af4da95..6b77b7762745bac473d5b59a6aee447ef104fd5d 100644
--- a/embedded/README.md
+++ b/embedded/README.md
@@ -32,4 +32,6 @@ In any case, I'd say it's enough to start trying to cut things, with some more c
 
 I know I can do this if I can manage to read my encoder successfully. I could also probably do it with the ADC, but I would want an oscilloscope to go down that path, and I don't have one here.
 
-So, we use a logic analyzer to try reading this AMS5047
\ No newline at end of file
+So, we use a logic analyzer to try reading this AMS5047
+
+Got this running, feels pretty mediocre. I need to understand commutation a bit better, and do this with a fan setup etc. I perhaps just have not counted my poles properly, but I wamt to do this with an oscilloscope, and understand how we might search for those offsets etc. 
\ No newline at end of file
diff --git a/embedded/atkbldcdriver/atkbldcdriver/ams5047.c b/embedded/atkbldcdriver/atkbldcdriver/ams5047.c
index 651c21bb183d85ed85c48811728ead301ae1aa30..c19ebcd2cc73288f76919a5a82733cbc7965abb2 100644
--- a/embedded/atkbldcdriver/atkbldcdriver/ams5047.c
+++ b/embedded/atkbldcdriver/atkbldcdriver/ams5047.c
@@ -7,34 +7,20 @@
 
 #include "ams5047.h"
 
-void ams5047_init(ams5047_t *ams, spiport_t *spi, pin_t *en, pin_t *sg){	
+void ams5047_init(ams5047_t *ams, spiport_t *spi){
 	ams->spi = spi;
-	ams->en_pin = en;
-	ams->sg_pin = sg;
+	ams5047_readOp = (1 << 15) | (1 << 14) | 0x3FFF; // parity bit, 1 for read / notwrite, 1s for read-op address
+	ams5047_readBytes[0] = ams5047_readOp >> 8;
+	ams5047_readBytes[1] = (uint8_t)ams5047_readOp;
+	ams5047_noOp = (1 << 15);  // parity bit, 0's for no-op
+	ams5047_noOpBytes[0] = ams5047_noOp >> 8;
+	ams5047_noOpBytes[1] = (uint8_t)ams5047_noOp;
 }
 
-void ams5047_write(ams5047_t *ams, uint32_t 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(ams->spi, bytes, 3);
-}
-
-void ams5047_start(ams5047_t *ams){
-	//
-}
-
-void ams5047_update(ams5047_t *ams){
-	uint32_t smarten = 0b10100000000000000000;
-	ams5047_write(ams, smarten);
-}
-
-void ams5047_enable(ams5047_t *ams){
-	pin_clear(ams->en_pin);
-}
-
-void ams5047_disable(ams5047_t *ams){
-	pin_set(ams->en_pin);
+void ams5047_read(ams5047_t *ams, uint16_t *result){
+	// at baud, takes ~ 20us (bauda = 12, baudb = 0) so max 50kHz
+	spi_txchars_polled(ams->spi, ams5047_readBytes, 2);
+	// issue noop, read rx'd on this tx (one step back)
+	spi_txrxchars_polled(ams->spi, ams5047_readBytes, ams5047_resultBytes, 2);
+	*result = ((ams5047_resultBytes[0] & 0b00111111) << 8) | ams5047_resultBytes[1];
 }
\ No newline at end of file
diff --git a/embedded/atkbldcdriver/atkbldcdriver/ams5047.h b/embedded/atkbldcdriver/atkbldcdriver/ams5047.h
index 3b560b2f4bc5511679d94e47a4593958c118dfdb..04c695d302612b8f49b382e4c6ce21097f8d1d73 100644
--- a/embedded/atkbldcdriver/atkbldcdriver/ams5047.h
+++ b/embedded/atkbldcdriver/atkbldcdriver/ams5047.h
@@ -18,21 +18,17 @@
 
 typedef struct{
 	spiport_t *spi;
-	
-	pin_t *en_pin;
-	pin_t *sg_pin;
 }ams5047_t;
 
-void ams5047_init(ams5047_t *ams, spiport_t *spi, pin_t *en, pin_t *sg);
+uint16_t ams5047_readOp;
+uint16_t ams5047_noOp;
+uint8_t ams5047_readBytes[2];
+uint8_t ams5047_noOpBytes[2];
 
-void ams5047_write(ams5047_t *ams, uint32_t word);
+uint8_t ams5047_resultBytes[2];
 
-void ams5047_start(ams5047_t *ams);
+void ams5047_init(ams5047_t *ams, spiport_t *spi);
 
-void ams5047_update(ams5047_t *ams);
-
-void ams5047_enable(ams5047_t *ams);
-
-void ams5047_disable(ams5047_t *ams);
+void ams5047_read(ams5047_t *ams, uint16_t *result);
 
 #endif /* AMS5047_H_ */
\ No newline at end of file
diff --git a/embedded/atkbldcdriver/atkbldcdriver/main.c b/embedded/atkbldcdriver/atkbldcdriver/main.c
index 2669daf701f7411ecf08257a96b94c6103cf995c..06de01e01aced7d936959b696b037a988df0fb7b 100644
--- a/embedded/atkbldcdriver/atkbldcdriver/main.c
+++ b/embedded/atkbldcdriver/atkbldcdriver/main.c
@@ -43,9 +43,12 @@ void atkps_init(void){
 }
 
 void encoder_init(void){
+	// startup SPI
 	pin_init(&spiEncCsPin, &PORTD, PIN4_bm, 4, 1);
 	spi_init(&spiEncoder, &USARTD1, &PORTD, PIN6_bm, PIN7_bm, PIN5_bm, &spiEncCsPin);
-	spi_start(&spiEncoder, 0);
+	spi_start(&spiEncoder, 1);
+	// startup object 
+	ams5047_init(&ams5047, &spiEncoder);
 }
 
 void pwm_periods(uint16_t peru, uint16_t perv, uint16_t perw){
@@ -135,8 +138,7 @@ void tickers_init(void){
 	// sets up two timers
 	
 	// compare and capture at value
-	// this is a low-speed-start friendly value, to start the commutation ticker with 
-	uint16_t perStartSpeed = 2400; 
+	uint16_t perStartSpeed = 150; // 75 should be 10kHz for commutation, 150 for 5kHz 
 	// write low first, bc bussing / xmega 8-bit oddities cc datasheet @ 3.11
 	uint8_t perSl = (uint8_t) perStartSpeed;
 	uint8_t perSh = (uint8_t) (perStartSpeed >> 8);
@@ -149,6 +151,7 @@ void tickers_init(void){
 	// set cca interrupt on
 	TCD0.INTCTRLA = TC_OVFINTLVL_HI_gc;
 	
+	/*
 	// and a reasonable speed for acceleration ticking
 	
 	uint16_t perAccelRate = 800;
@@ -161,6 +164,7 @@ void tickers_init(void){
 	TCD1.PERBUFH = perAh;
 	
 	TCD1.INTCTRLA = TC_OVFINTLVL_HI_gc;
+	*/
 }
 
 int main(void)
@@ -178,33 +182,28 @@ int main(void)
 	pin_set(&stlerr);
 	pin_set(&stlclk);
 	
-	//pin_init(&tstpin1, &PORTC, PIN5_bm, 5, 1);
-	//pin_init(&tstpin2, &PORTC, PIN3_bm, 3, 1);
-	
+	// startup encoder
+	encoder_init();
 	// start timers for commutation, accel tickers 
 	tickers_init();
-	// startup encoder
-	//encoder_init();
 	
 	// start pwm system
 	pwm_init();
 	// initialize the bldc state structure
 	bldc_init(&bldc);
-	// on startup speed and duty
-	bldc_setTargetSpeed(&bldc, 1000);
-	bldc_setDuty(&bldc, 10);
+	// on startup, speed (if clcomm) and duty
+	//bldc_setTargetSpeed(&bldc, 1000);
+	bldc_setDuty(&bldc, 40);
 	// startup the driver
 	drv_init();
 	// and enable the gate
 	drv_enable();
-	// now we should be spinning at 500 eRPM, so we can set an accel... later
 
 	// runtime globals
 	uint32_t tck = 0;
 
 	while (1)
 	{
-		//ams5047_write(&ams5047, 1200);
 		atkport_scan(&atkp0, 2);
 		// just... as fast as we can 
  		tck++;
@@ -216,10 +215,6 @@ int main(void)
 	}
 }
 
-ISR(TCC0_OVF_vect){
-	pin_toggle(&hi1);
-}
-
 int8_t comTable[6][3] = {
 	{1,-1,0},
 	{1,0,-1},
@@ -229,9 +224,48 @@ int8_t comTable[6][3] = {
 	{0,-1,1}
 };
 
+#define ENC_RESOLUTION 16834
+
+// a handful of constants, probably need many less
+// divisor is # of poles on motor / 2 (for each n/s pair, one set of 3 coils per full rotation)
+const static uint16_t enc_resolution = ENC_RESOLUTION;
+const static uint8_t enc_reverse = 0; // 1 or 0, for reverse op
+const static uint16_t enc_modulo = ENC_RESOLUTION / 4; // 2805 in this case: divisor is # poles / 2
+const static uint16_t enc_offset = 60; // start at midpoint - adjust -ve or +ve from
+const static uint16_t enc_steplength = ENC_RESOLUTION / 4 / 6;
+static uint16_t enc_reading = 0;
+static uint16_t enc_adjusted = 0;
+static uint16_t enc_phase = 0;
+static uint16_t enc_target = 0;
+// 2^14 = 16,384
+
 // commutation timer
 ISR(TCD0_OVF_vect){
-	// commutate?
+	// CL 6-step Commutate
+	
+	// get encoder reading
+	ams5047_read(&ams5047, &enc_reading);
+	// offset and modulo to bring to in-phase relative location
+	if(enc_reverse){
+		enc_adjusted = enc_resolution - enc_reading;
+	}
+	enc_adjusted += enc_offset; // add offset
+	enc_adjusted %= enc_resolution; // wrap to resolution
+	enc_adjusted %= enc_modulo; // break into phase relative
+	// so this should represent the phase (0-5) that we're currently in
+	enc_phase = enc_adjusted / enc_steplength;
+	// if dir, phase + 2 to go forwards, else + 4, effectively - 2, and wrap past circle
+	(bldc.comDir) ? (enc_target = (enc_phase + 2) % 6) : (enc_target = (enc_phase + 4) % 6);
+	//uint8_t dout[6] = {6,0,5,254,255,enc_target};
+	//uart_sendchars_buffered(&up0, dout, 6);
+	// now we can set PWMs accordingly
+	pwm_by_offset(	comTable[enc_target][0] * bldc.comDuty,
+					comTable[enc_target][1] * bldc.comDuty,
+					comTable[enc_target][2] * bldc.comDuty
+				 );
+				 
+	// OL Commutate
+	/*
 	(bldc.comDir) ? (bldc.comState ++) : (bldc.comState --);
 	if(bldc.comState > 5){
 		bldc.comState = 0;
@@ -241,10 +275,15 @@ ISR(TCD0_OVF_vect){
 					comTable[bldc.comState][1] * bldc.comDuty,
 					comTable[bldc.comState][2] * bldc.comDuty 
 				 );
+	*/
 }
 
 // acceleration timer
 ISR(TCD1_OVF_vect){
+	// CL Commutate: PID Speed Loop
+	
+	// OL Commutate: Acceleration to Speed
+	/*
 	if(bldc.currentSpeed != bldc.targetSpeed){
 		if(bldc.currentSpeed < bldc.targetSpeed){
 			bldc.currentSpeed ++;
@@ -254,6 +293,7 @@ ISR(TCD1_OVF_vect){
 			bldc_setSpeed(&bldc, bldc.currentSpeed);
 		}
 	}
+	*/
 }
 
 ISR(USARTE1_RXC_vect){
diff --git a/embedded/atkbldcdriver/atkbldcdriver/spiport.c b/embedded/atkbldcdriver/atkbldcdriver/spiport.c
index a7698bc628f04f00f6730ef8df697754c951b9ed..b59d12b3c58b753d68c818f45e551c01f859dc64 100644
--- a/embedded/atkbldcdriver/atkbldcdriver/spiport.c
+++ b/embedded/atkbldcdriver/atkbldcdriver/spiport.c
@@ -23,8 +23,8 @@ void spi_start(spiport_t *spi, uint8_t cpha){
 	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->BAUDCTRLA = 12; //130;
+	spi->com->BAUDCTRLB = 0; //USART_BSCALE3_bm | USART_BSCALE2_bm | USART_BSCALE1_bm | USART_BSCALE0_bm;
 	
 	spi->com->CTRLB = USART_TXEN_bm | USART_RXEN_bm;
 	
@@ -42,13 +42,23 @@ void spi_txchar_polled(spiport_t *spi, uint8_t 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->com->STATUS |= USART_TXCIF_bm; // clear transmit complete flag
 		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?
+void spi_txrxchars_polled(spiport_t *spi, uint8_t *data, uint8_t *result, uint8_t length){
+	pin_clear(spi->csn);
+	for(int i = 0; i < length; i ++){
+		// rm'd extra clear of txcomplete flag
+		while(!(spi->com->STATUS & USART_DREIF_bm)); // wait for data register empty
+		spi->com->STATUS |= USART_TXCIF_bm; // clear transmit complete flag
+		spi->com->DATA = data[i]; // tx this
+		while(!(spi->com->STATUS & USART_TXCIF_bm)); // wait for complete before
+		while(!(spi->com->STATUS & USART_RXCIF_bm)); // wait for rx complete 
+		result[i] = spi->com->DATA; // this is incoming (when read DATA reg, rx, when write, TX)
+	}
+	pin_set(spi->csn);
 }
\ No newline at end of file
diff --git a/embedded/atkbldcdriver/atkbldcdriver/spiport.h b/embedded/atkbldcdriver/atkbldcdriver/spiport.h
index cd5e5aa10ae4d4a5f85c73acd785d2b727d67650..dd4f013cdb1f39c086a435fbc171466a81e6da47 100644
--- a/embedded/atkbldcdriver/atkbldcdriver/spiport.h
+++ b/embedded/atkbldcdriver/atkbldcdriver/spiport.h
@@ -30,6 +30,7 @@ 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);
+void spi_txrxchars_polled(spiport_t *spi, uint8_t *data, uint8_t *result, uint8_t length);
 
 
 #endif /* SPIPORT_H_ */
\ No newline at end of file