diff --git a/embedded/README.md b/embedded/README.md
index 8a7aa74a714c7dfaf5536b713450b1d07f2f95b5..275f667ecfd99dd3ef48e41a9d50532133d65c98 100644
--- a/embedded/README.md
+++ b/embedded/README.md
@@ -326,4 +326,179 @@ So this shortened motor wires did seem to really kill the problem. Fin.
 
 We're going to do this on the ATSAMD51, now. I have a v0.3 board here (which will shortly be rev'd to 0.31 due to a few already apparent mistakes, welp) and I can program it. I'm in the process of checking all of the hardware so that I can go forward with a new board order, knowing a bit better that I'll be o-k with that set. 
 
-So! I want to set up the project and check my clock settings and interrupts for good measure. 
\ No newline at end of file
+I've got the PWM up, and it's running as expected. Nice.
+
+```C
+
+int main(void)
+{
+    /* Initialize the SAM system */
+    SystemInit();
+	
+	PORT->Group[1].DIRSET.reg |= (uint32_t)(1 << 9);
+	PORT->Group[0].DIRSET.reg |= (uint32_t)(1 << 23);
+	
+	SysTick_Config(5000000);
+	
+	/* TCC SETUP */
+	// from 49.6.2.1
+	// a few registers are protected - and can only be updated when
+	// TCCn.CTRLA.ENABLE = 0
+	// FCTRLA and FCTRLB, WEXCTRL, DRVCTRL, and EVCTRL
+	
+	// (4) Configure Output Pin with PORT->Group[n].DIRSET.reg
+	// PA8 PA9 PA10 PA12, PB10 PB11
+	// 32.9.13
+	PORT->Group[0].DIRSET.reg |= (uint32_t)(1 << 8) | (uint32_t)(1 << 9) | (uint32_t)(1 << 10) | (uint32_t)(1 << 12);
+	PORT->Group[1].DIRSET.reg |= (uint32_t)(1 << 10) | (uint32_t)(1 << 11);
+	
+	// 1 lo / hi
+	PORT->Group[0].PINCFG[10].bit.PMUXEN = 1;
+	PORT->Group[0].PMUX[10>>1].reg |= PORT_PMUX_PMUXE(0x5);  // on peripheral F
+	PORT->Group[0].PINCFG[12].bit.PMUXEN = 1;
+	PORT->Group[0].PMUX[12>>1].reg |= PORT_PMUX_PMUXE(0x5); 
+	
+	// 2 lo / hi
+	PORT->Group[0].PINCFG[9].bit.PMUXEN = 1;
+	PORT->Group[0].PMUX[9>>1].reg |= PORT_PMUX_PMUXO(0x5);  // on peripheral F
+	PORT->Group[1].PINCFG[11].bit.PMUXEN = 1;
+	PORT->Group[1].PMUX[11>>1].reg |= PORT_PMUX_PMUXO(0x5);
+	
+	// 3 lo / hi
+	PORT->Group[0].PINCFG[8].bit.PMUXEN = 1;
+	PORT->Group[0].PMUX[8>>1].reg |= PORT_PMUX_PMUXE(0x5);  // on peripheral F
+	PORT->Group[1].PINCFG[10].bit.PMUXEN = 1;
+	PORT->Group[1].PMUX[10>>1].reg |= PORT_PMUX_PMUXE(0x5);
+	
+	// (1) enable the TCC Bus Clock - CLK_TCCn_APB
+	// https://www.eevblog.com/forum/microcontrollers/atmel-sam-d-tc-and-tcc-(no-asf)/
+	
+	TCC0->CTRLA.bit.ENABLE = 0;
+	
+	MCLK->APBBMASK.reg |= MCLK_APBBMASK_TCC0; // at 15.8.9
+	
+	GCLK->GENCTRL[5].reg = GCLK_GENCTRL_SRC(GCLK_GENCTRL_SRC_DFLL) | GCLK_GENCTRL_GENEN;
+	while(GCLK->SYNCBUSY.reg & GCLK_SYNCBUSY_GENCTRL5);
+	
+	GCLK->PCHCTRL[TCC0_GCLK_ID].reg = GCLK_PCHCTRL_CHEN | GCLK_PCHCTRL_GEN_GCLK5;
+	
+	TCC0->CTRLA.reg |= TCC_CTRLA_PRESCALER_DIV8 | TCC_CTRLA_PRESCSYNC_PRESC |TCC_CTRLA_RESOLUTION(0);
+	
+	// (2) Select Waveform Generation operation in the WAVE register WAVE.WAVEGEN
+	// we want dual slope pwm
+		
+	TCC0->WAVE.reg = TCC_WAVE_WAVEGEN_DSBOTH; // 'dual slope both' - updates on both hi and lo of slope ?
+		
+	// (3) We want OTMX - Output Matrix Channel Pin Routing Configuration - at 0x0
+	
+	TCC0->WEXCTRL.reg = TCC_WEXCTRL_DTHS(1) | TCC_WEXCTRL_DTLS(1) | 
+						TCC_WEXCTRL_DTIEN1 | TCC_WEXCTRL_DTIEN2 | TCC_WEXCTRL_DTIEN3 | TCC_WEXCTRL_DTIEN0 |
+						TCC_WEXCTRL_OTMX(0);
+						
+	TCC0->PER.reg = TCC_PER_PER(256); // 18 bit
+	
+	TCC0->COUNT.reg = 0;
+	
+	TCC0->CC[0].reg = 12; // '3'
+	TCC0->CC[1].reg = 24; // '2'
+	TCC0->CC[2].reg = 48; // '1'
+	TCC0->CC[3].reg = 0;
+	
+	// (4) Enable with CTRLA.ENABLE
+	
+	TCC0->CTRLA.bit.ENABLE = 1;
+	while(TCC0->SYNCBUSY.bit.ENABLE);
+
+    while (1) 
+    {
+		PORT->Group[1].OUTTGL.reg = (uint32_t)(1 << 9);
+    }
+}
+```
+
+![atsamd51 pwm](https://gitlab.cba.mit.edu/jakeread/mkbldcdriver/raw/master/images/programming-pwm-alive-atsamd51.png)
+
+![atsamd51 pwm](https://gitlab.cba.mit.edu/jakeread/mkbldcdriver/raw/master/images/programming-pwm-alive-atsamd51-picture.jpg)
+
+Next up is the SPI wakeup.
+
+Great, this is running as well.
+
+```C
+int main(void)
+{
+    /* Initialize the SAM system */
+    SystemInit();
+	
+	PORT->Group[1].DIRSET.reg |= (uint32_t)(1 << 9);
+	PORT->Group[0].DIRSET.reg |= (uint32_t)(1 << 23);
+	
+	SysTick_Config(5000000);
+	
+	/* BEGIN SPI SETUP */
+	
+	// PA04, SER0-0, SPI_MISO
+	// PA05, SER0-1, SPI_SCK
+	// PA06, SER0-2, SPI_CSN
+	// PA07, SER0-3, SPI_MOSI
+	PORT->Group[0].DIRCLR.reg |= (uint32_t)(1 << 4); 
+	PORT->Group[0].DIRSET.reg |= (uint32_t)(1 << 5) | (uint32_t)(1 << 6) | (uint32_t)(1 << 7);
+	
+	PORT->Group[0].PINCFG[4].bit.PMUXEN = 1;
+	PORT->Group[0].PMUX[4>>1].reg |= PORT_PMUX_PMUXE(0x3);  // on peripheral D
+	PORT->Group[0].PINCFG[5].bit.PMUXEN = 1;
+	PORT->Group[0].PMUX[5>>1].reg |= PORT_PMUX_PMUXO(0x3);  // on peripheral D
+	PORT->Group[0].PINCFG[6].bit.PMUXEN = 1;
+	PORT->Group[0].PMUX[6>>1].reg |= PORT_PMUX_PMUXE(0x3);  // on peripheral D
+	PORT->Group[0].PINCFG[7].bit.PMUXEN = 1;
+	PORT->Group[0].PMUX[7>>1].reg |= PORT_PMUX_PMUXO(0x3);  // on peripheral D
+	
+	// setup clocks to sercom
+	
+	MCLK->APBAMASK.reg |= MCLK_APBAMASK_SERCOM0; // at 15.8.9
+	
+	GCLK->GENCTRL[6].reg = GCLK_GENCTRL_SRC(GCLK_GENCTRL_SRC_DFLL) | GCLK_GENCTRL_GENEN;
+	while(GCLK->SYNCBUSY.reg & GCLK_SYNCBUSY_GENCTRL6);
+	
+	GCLK->PCHCTRL[SERCOM0_GCLK_ID_CORE].reg = GCLK_PCHCTRL_CHEN | GCLK_PCHCTRL_GEN_GCLK6;
+	
+	// TCC0_GCLK_ID
+	
+	// Some registers can't be written unless CTRL.ENABLE = 0:
+	// CTRLA, CTRLB, BAD and ADDR
+	
+	// (1) set to master
+	
+	SERCOM0->SPI.CTRLA.reg |= SERCOM_SPI_CTRLA_MODE(0x3); // 0x2 or 0x3, slave or master
+	
+	// SERCOM0->SPI.CTRLA.reg |= SERCOM_SPI_CTRLA_CPHA | SERCOM_SPI_CTRLA_CPOL; // clock phase and polarity
+	
+	// (2) set pin configurations
+	
+	SERCOM0->SPI.CTRLA.reg |= SERCOM_SPI_CTRLA_DIPO(0x0) | SERCOM_SPI_CTRLA_DOPO(0x2); // pin selections, see 35.8.1 bits 21:20 and 17:16, pg. 910
+	
+	// (3) set character size, data direction
+	
+	//SERCOM0->SPI.CTRLA.reg |= SERCOM_SPI_CTRLA_DORD; // 0 MSB, 1 LSB
+	//SERCOM0->SPI.CTRLB.reg |= SERCOM_SPI_CTRLB_CHSIZE(0x0); // 8 bits character - 0x0, so no need to set
+	
+	// (4) setup baud rate
+	// f_baud = f_ref / (2 * (BAUD +1)) so BAUD = f_ref / (2 * f_baud) - 1
+	
+	SERCOM0->SPI.BAUD.reg |= SERCOM_SPI_BAUD_BAUD(126);
+	SERCOM0->SPI.CTRLB.reg |= SERCOM_SPI_CTRLB_MSSEN | SERCOM_SPI_CTRLB_RXEN; // slave select hardware yes
+	
+	SERCOM0->SPI.CTRLA.reg |= SERCOM_SPI_CTRLA_ENABLE;
+	
+    while (1) 
+    {
+		while(!(SERCOM0->SPI.INTFLAG.bit.DRE));
+		SERCOM0->SPI.DATA.reg = SERCOM_SPI_DATA_DATA(80);
+		PORT->Group[1].OUTTGL.reg = (uint32_t)(1 << 9); // i-v, to check we made it thru setup
+    }
+}
+```
+
+![atsamd51 spi](https://gitlab.cba.mit.edu/jakeread/mkbldcdriver/raw/master/images/programming-spi-alive-atsamd51.png)
+
+Now we do v0.31 board, new step board, etc. Go team, big day.
\ No newline at end of file
diff --git a/embedded/mkbldcdriver-v03/.vs/mkbldcdriver-v03/v14/.atsuo b/embedded/mkbldcdriver-v03/.vs/mkbldcdriver-v03/v14/.atsuo
index 091e0e9973aa6d32a1ff82f521bfff5bf040ee90..6cb941a9f4c80642687368b0956373ae5910d32a 100644
Binary files a/embedded/mkbldcdriver-v03/.vs/mkbldcdriver-v03/v14/.atsuo and b/embedded/mkbldcdriver-v03/.vs/mkbldcdriver-v03/v14/.atsuo differ
diff --git a/embedded/mkbldcdriver-v03/mkbldcdriver-v03/main.c b/embedded/mkbldcdriver-v03/mkbldcdriver-v03/main.c
index a046b9826cba51795646176dce7602d9b906dde6..5fb245e181e7ae4c5b61d869b2db8e73972cc469 100644
--- a/embedded/mkbldcdriver-v03/mkbldcdriver-v03/main.c
+++ b/embedded/mkbldcdriver-v03/mkbldcdriver-v03/main.c
@@ -11,16 +11,7 @@
 
 // stlb is PA23
 
-int main(void)
-{
-    /* Initialize the SAM system */
-    SystemInit();
-	
-	PORT->Group[1].DIRSET.reg |= (uint32_t)(1 << 9);
-	PORT->Group[0].DIRSET.reg |= (uint32_t)(1 << 23);
-	
-	SysTick_Config(5000000);
-	
+void pwmsetup(void){
 	/* TCC SETUP */
 	// from 49.6.2.1
 	// a few registers are protected - and can only be updated when
@@ -80,19 +71,93 @@ int main(void)
 	
 	TCC0->COUNT.reg = 0;
 	
-	TCC0->CC[0].reg = 12; // '3'
-	TCC0->CC[1].reg = 24; // '2'
-	TCC0->CC[2].reg = 48; // '1'
+	TCC0->CC[0].reg = 0; // '3'
+	TCC0->CC[1].reg = 0; // '2'
+	TCC0->CC[2].reg = 0; // '1'
 	TCC0->CC[3].reg = 0;
 	
 	// (4) Enable with CTRLA.ENABLE
 	
 	TCC0->CTRLA.bit.ENABLE = 1;
 	while(TCC0->SYNCBUSY.bit.ENABLE);
+}
 
+void pwmupdate(uint32_t one, uint32_t two, uint32_t three){
+	TCC0->CC[0].reg = three; // '3'
+	TCC0->CC[1].reg = two; // '2'
+	TCC0->CC[2].reg = one; // '1'
+}
+
+int main(void)
+{
+    /* Initialize the SAM system */
+    SystemInit();
+	
+	PORT->Group[1].DIRSET.reg |= (uint32_t)(1 << 9);
+	PORT->Group[0].DIRSET.reg |= (uint32_t)(1 << 23);
+	
+	SysTick_Config(5000000);
+	
+	/* BEGIN SPI SETUP */
+	
+	// PA04, SER0-0, SPI_MISO
+	// PA05, SER0-1, SPI_SCK
+	// PA06, SER0-2, SPI_CSN
+	// PA07, SER0-3, SPI_MOSI
+	PORT->Group[0].DIRCLR.reg |= (uint32_t)(1 << 4); 
+	PORT->Group[0].DIRSET.reg |= (uint32_t)(1 << 5) | (uint32_t)(1 << 6) | (uint32_t)(1 << 7);
+	
+	PORT->Group[0].PINCFG[4].bit.PMUXEN = 1;
+	PORT->Group[0].PMUX[4>>1].reg |= PORT_PMUX_PMUXE(0x3);  // on peripheral D
+	PORT->Group[0].PINCFG[5].bit.PMUXEN = 1;
+	PORT->Group[0].PMUX[5>>1].reg |= PORT_PMUX_PMUXO(0x3);  // on peripheral D
+	PORT->Group[0].PINCFG[6].bit.PMUXEN = 1;
+	PORT->Group[0].PMUX[6>>1].reg |= PORT_PMUX_PMUXE(0x3);  // on peripheral D
+	PORT->Group[0].PINCFG[7].bit.PMUXEN = 1;
+	PORT->Group[0].PMUX[7>>1].reg |= PORT_PMUX_PMUXO(0x3);  // on peripheral D
+	
+	// setup clocks to sercom
+	
+	MCLK->APBAMASK.reg |= MCLK_APBAMASK_SERCOM0; // at 15.8.9
+	
+	GCLK->GENCTRL[6].reg = GCLK_GENCTRL_SRC(GCLK_GENCTRL_SRC_DFLL) | GCLK_GENCTRL_GENEN;
+	while(GCLK->SYNCBUSY.reg & GCLK_SYNCBUSY_GENCTRL6);
+	
+	GCLK->PCHCTRL[SERCOM0_GCLK_ID_CORE].reg = GCLK_PCHCTRL_CHEN | GCLK_PCHCTRL_GEN_GCLK6;
+	
+	// TCC0_GCLK_ID
+	
+	// Some registers can't be written unless CTRL.ENABLE = 0:
+	// CTRLA, CTRLB, BAD and ADDR
+	
+	// (1) set to master
+	
+	SERCOM0->SPI.CTRLA.reg |= SERCOM_SPI_CTRLA_MODE(0x3); // 0x2 or 0x3, slave or master
+	
+	// SERCOM0->SPI.CTRLA.reg |= SERCOM_SPI_CTRLA_CPHA | SERCOM_SPI_CTRLA_CPOL; // clock phase and polarity
+	
+	// (2) set pin configurations
+	
+	SERCOM0->SPI.CTRLA.reg |= SERCOM_SPI_CTRLA_DIPO(0x0) | SERCOM_SPI_CTRLA_DOPO(0x2); // pin selections, see 35.8.1 bits 21:20 and 17:16, pg. 910
+	
+	// (3) set character size, data direction
+	
+	//SERCOM0->SPI.CTRLA.reg |= SERCOM_SPI_CTRLA_DORD; // 0 MSB, 1 LSB
+	//SERCOM0->SPI.CTRLB.reg |= SERCOM_SPI_CTRLB_CHSIZE(0x0); // 8 bits character - 0x0, so no need to set
+	
+	// (4) setup baud rate
+	// f_baud = f_ref / (2 * (BAUD +1)) so BAUD = f_ref / (2 * f_baud) - 1
+	
+	SERCOM0->SPI.BAUD.reg |= SERCOM_SPI_BAUD_BAUD(126);
+	SERCOM0->SPI.CTRLB.reg |= SERCOM_SPI_CTRLB_MSSEN | SERCOM_SPI_CTRLB_RXEN; // slave select hardware yes
+	
+	SERCOM0->SPI.CTRLA.reg |= SERCOM_SPI_CTRLA_ENABLE;
+	
     while (1) 
     {
-		PORT->Group[1].OUTTGL.reg = (uint32_t)(1 << 9);
+		while(!(SERCOM0->SPI.INTFLAG.bit.DRE));
+		SERCOM0->SPI.DATA.reg = SERCOM_SPI_DATA_DATA(80);
+		PORT->Group[1].OUTTGL.reg = (uint32_t)(1 << 9); // i-v, to check we made it thru setup
     }
 }
 
diff --git a/images/programming-pwm-alive-atsamd51-picture.jpg b/images/programming-pwm-alive-atsamd51-picture.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..448c0937c023dd6756f9c98f1a6d7564e6a521f9
Binary files /dev/null and b/images/programming-pwm-alive-atsamd51-picture.jpg differ
diff --git a/images/programming-pwm-alive-atsamd51.png b/images/programming-pwm-alive-atsamd51.png
new file mode 100644
index 0000000000000000000000000000000000000000..6dca6d5ffdcaa1bdd919335d2c4ed11ff3afedb4
Binary files /dev/null and b/images/programming-pwm-alive-atsamd51.png differ
diff --git a/images/programming-spi-alive-atsamd51.png b/images/programming-spi-alive-atsamd51.png
new file mode 100644
index 0000000000000000000000000000000000000000..eef6050dd32c2dd59ee0fa5b2c93604e7d0ff29d
Binary files /dev/null and b/images/programming-spi-alive-atsamd51.png differ