diff --git a/rpi_spi/2023-12-29_pi-spi-rates.md b/rpi_spi/2023-12-29_pi-spi-rates.md
index b4114ad6b840ce87ba71df1cd4754e447e9921b8..cc1acd0303d72af7d84a3f934261d38240052691 100644
--- a/rpi_spi/2023-12-29_pi-spi-rates.md
+++ b/rpi_spi/2023-12-29_pi-spi-rates.md
@@ -81,4 +81,6 @@ We are normally pulling one byte at a time - if we want to be catching while we
 
 OK, so to see if we can get up to that 10Mbit real-transfer-rate target, I think I will start with an echo test - since SPI is transfer-based anyways (we always send data when we get it), I'll program some arduino to get packets and echo them, and we'll turn the speed up until we start making mistakes. 
 
-I have hello-worlded this with the Earle Core, but their SPI implementation is strange - since it's simple enough (I'm starting to see that... that's the pint), I'll just roll my own... listening to CS down / up interrupts to frame packets, stuffing buffers, you know the dealio. It's 730pm here but that's just time to put the embedded hardo hat on... 
\ No newline at end of file
+I have hello-worlded this with the Earle Core, but their SPI implementation is strange - since it's simple enough (I'm starting to see that... that's the pint), I'll just roll my own... listening to CS down / up interrupts to frame packets, stuffing buffers, you know the dealio. It's 730pm here but that's just time to put the embedded hardo hat on... 
+
+I'm going a bit mad with this; I can get GPIO interrupts to fire *just on a falling edge* but not *just on a rising edge* ... I should see if I can access some lower level masks, or something? But it's genuinely sending events *marked* as *rising edge* events on falling and rising edges... 
\ No newline at end of file
diff --git a/rpi_spi/code/spi_peripheral_bare/screen.cpp b/rpi_spi/code/spi_peripheral_bare/screen.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..9ff9e8d48bc2dfcf6cb5e7741c9333373e285921
--- /dev/null
+++ b/rpi_spi/code/spi_peripheral_bare/screen.cpp
@@ -0,0 +1,42 @@
+#include "screen.h"
+#include <Adafruit_GFX.h>
+#include <Adafruit_SSD1306.h>
+#include <Wire.h>
+
+// OLED 
+#define SCREEN_WIDTH 128 // OLED display width, in pixels
+#define SCREEN_HEIGHT 64 // OLED display height, in pixels
+
+#define X_POS 0
+#define Y_POS 0
+#define TXT_SIZE 1
+
+// even for displays with i.e. "0x78" printed on the back, 
+// the address that works is 0x3C, IDK 
+#define SCREEN_ADDRESS 0x3C
+
+Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire1);
+
+// warning: is blocking, takes ~ 33ms ! 
+void displayPrint(String msg){
+  display.clearDisplay();
+  display.setCursor(X_POS, Y_POS);
+  display.print(msg);
+  display.display();
+}
+
+void displaySetup(void){
+  Wire1.setSDA(2);
+  Wire1.setSCL(3);
+
+  // initialize the screen,
+  // oddly, SWITCHCAPVCC is the option that works even though OLED is hooked to 5V 
+  display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS);
+  display.clearDisplay();
+  display.display();
+  display.setTextColor(SSD1306_WHITE);
+  display.setTextSize(TXT_SIZE);
+  display.setTextWrap(true);
+  display.dim(false);
+  displayPrint("bonjour...");
+}
\ No newline at end of file
diff --git a/rpi_spi/code/spi_peripheral_bare/screen.h b/rpi_spi/code/spi_peripheral_bare/screen.h
new file mode 100644
index 0000000000000000000000000000000000000000..91fb08f0bd738345349813ee51aec5739694a9f9
--- /dev/null
+++ b/rpi_spi/code/spi_peripheral_bare/screen.h
@@ -0,0 +1,9 @@
+#ifndef SCREEN_H_
+#define SCREEN_H_
+
+#include <Arduino.h>
+
+void displaySetup(void);
+void displayPrint(String msg);
+
+#endif 
\ No newline at end of file
diff --git a/rpi_spi/code/spi_peripheral_bare/spi_peripheral_bare.ino b/rpi_spi/code/spi_peripheral_bare/spi_peripheral_bare.ino
new file mode 100644
index 0000000000000000000000000000000000000000..2bdb72f7cf1d8c3fc1c1ad57dd4e7baae9e02b2d
--- /dev/null
+++ b/rpi_spi/code/spi_peripheral_bare/spi_peripheral_bare.ino
@@ -0,0 +1,85 @@
+#include "spipi.h"
+#include "screen.h"
+
+// using a (basically raspberry pi pico) W5500-EVB-Pico 
+// with earle philhower core 
+
+#define PIN_DEBUG 1
+
+// SPI 
+// SPISettings settings(1000000, MSBFIRST, SPI_MODE0);
+
+uint8_t txBuffer[1024];
+volatile uint32_t rxCount = 0;
+volatile uint32_t rxSize = 0;
+
+// fires when we get data, I presume ?
+// byte rxBuffer[1024];
+// this *is unrelated to the CS pin* but should be ! 
+// it actually fires basically every data chunk... 
+// void onRx(uint8_t* data, size_t len){
+//   // actually, for the echo we can copy 
+//   // directly across, non ? 
+//   // digitalWrite(PIN_DEBUG, HIGH);
+//   // memcpy(txBuffer, data, len);
+//   rxCount ++;
+//   if(len > rxSize) rxSize = len;
+
+//   // shifty shifty 
+//   // digitalWrite(PIN_DEBUG, LOW);
+// }
+
+// fires at the end of a transaction ?
+// void onTxComplete(void){
+//   SPISlave1.setData((uint8_t*)txBuffer, 32);
+//   digitalWrite(PIN_DEBUG, !digitalRead(PIN_DEBUG));
+// }
+
+void setup(void){
+  // a debug light and pin, 
+  pinMode(PIN_DEBUG, OUTPUT);
+  digitalWrite(PIN_DEBUG, LOW);
+
+  pinMode(LED_BUILTIN, OUTPUT);
+  digitalWrite(LED_BUILTIN, LOW);
+
+  // the display setup 
+  displaySetup();
+
+  // the spi setup 
+  spipi_begin();
+
+  // fill our demo buffer 
+  for(uint16_t i = 0; i < 1024; i ++){
+    txBuffer[i] = i;
+  }
+
+  // SPISlave1.setData((uint8_t*)txBuffer, 32);
+
+  // // pin config (2040 GPIO Nums)
+  // SPISlave1.setCS(13);
+  // SPISlave1.setSCK(10);
+  // SPISlave1.setRX(12);
+  // SPISlave1.setTX(11);
+
+  // // callbacks 
+  // SPISlave1.onDataRecv(onRx);
+  // SPISlave1.onDataSent(onTxComplete);
+
+  // // startup 
+  // SPISlave1.begin(settings);
+}
+
+uint32_t lastUpdate = 0;
+uint32_t updateInterval = 200;
+
+void loop(void){
+  if(lastUpdate + updateInterval < millis()){
+    lastUpdate = millis();
+    digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
+    displayPrint(String(rxCount) + "\n" + 
+      String(rxSize) + "\n" +
+      String(spipi_get_events())
+    );
+  }
+}
\ No newline at end of file
diff --git a/rpi_spi/code/spi_peripheral_bare/spipi.cpp b/rpi_spi/code/spi_peripheral_bare/spipi.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..0b06d2b5f063b24dccd142fdb8458e727aa1820a
--- /dev/null
+++ b/rpi_spi/code/spi_peripheral_bare/spipi.cpp
@@ -0,0 +1,112 @@
+#include "spipi.h"
+#include <hardware/spi.h>
+#include <hardware/gpio.h>
+
+// the relevant functions are here:
+// /jaker/AppData/Local/Arduino15/packages/rp2040/3.6.1/pico-sdk/src/ ...
+// /rp2040/rp2_common/hardware_spi/include/hardware/spi.h 
+
+// the registers we're interested in here:
+// /jaker/AppData/Local/Arduino15/packages/rp2040/3.6.1/pico-sdk/src/ ...
+// /rp2040/hardware_structs/include/hardware/structs/spi.h
+
+// for earle code reference, 
+// /jaker/AppData/Local/Arduino15/packages/rp2040/3.6.1/libraries/ ...
+// /SPISlave/src/SPISlave.cpp (etc) 
+
+// for gpio, 
+// /jaker/AppData/Local/Arduino15/packages/rp2040/3.6.1/pico-sdk/src/ ...
+// /rp2040/rp2_common/hardware_gpio/include/hardware/gpio.h 
+
+
+#define PIN_CS    14
+#define PIN_SCK   10 
+#define PIN_RX    12 
+#define PIN_TX    11 
+
+#define BITRATE   1000000
+
+#define SPI_INST  spi1 
+#define SPI_HW spi_get_hw(SPI_INST)
+
+#define SPI_IMSC_TXIM_ON  (1 << 3)
+#define SPI_IMSC_RXIM_ON  (1 << 2)
+#define SPI_IMSC_RTIM_ON  (1 << 1)
+#define SPI_IMSC_RORIM_ON (1)
+
+
+
+volatile uint32_t event_latest = 12;
+uint32_t spipi_get_events(void){
+  return event_latest;
+}
+
+// we catch rising edges to delineate packet-end
+void spipi_gpio_irq_handler(uint gpio, uint32_t events){
+  if(gpio_get(PIN_CS)){
+    gpio_put(1, !gpio_get_out_level(1));
+  }
+  // event_latest = events;
+  // if(events & GPIO_IRQ_EDGE_RISE){
+  //   gpio_put(1, !gpio_get_out_level(1));
+  // } else if (events & GPIO_IRQ_EDGE_FALL){
+  //   // gpio_put(1, !gpio_get_out_level(1));
+  // }
+}
+
+
+// void spipi_gpio_raw_handler(void){
+//   gpio_put(1, !gpio_get_out_level(1));
+//   if(gpio_get_irq_event_mask(PIN_CS) & GPIO_IRQ_EDGE_RISE){
+//     gpio_acknowledge_irq(PIN_CS, GPIO_IRQ_EDGE_RISE);
+//     gpio_put(1, !gpio_get_out_level(1));
+//   }
+// }
+
+
+void spipi_begin(void){
+  // uh ?
+  gpio_init(PIN_CS);
+  gpio_set_dir(PIN_CS, GPIO_IN);
+  
+  // let's actually just get the CS LOW/HI interrupt first, 
+  // so we can reset our buffer states (etc) 
+  // gpio_set_irq_enabled_with_callback(PIN_CS, GPIO_IRQ_EDGE_RISE | GPIO_IRQ_EDGE_FALL, false, &spipi_gpio_irq_handler);
+  gpio_set_irq_enabled_with_callback(PIN_CS, GPIO_IRQ_EDGE_RISE, true, &spipi_gpio_irq_handler);
+  // gpio_set_input_hysteresis_enabled(PIN_CS, false);
+
+  // or this simpler handler-thing ? 
+  // gpio_set_irq_enabled(PIN_CS, GPIO_IRQ_EDGE_RISE, true);
+  // gpio_add_raw_irq_handler(PIN_CS, &spipi_gpio_raw_handler);
+
+  // startup the peripheral ?
+  // spi_init(SPI_INST, BITRATE);
+  // spi_set_slave(SPI_INST, true);
+  // spi_set_format(SPI_INST, 8, SPI_CPOL_0, SPI_CPHA_0, SPI_MSB_FIRST);
+
+  // assign pins to SPI peripheral, 
+  // gpio_set_function(PIN_CS, GPIO_FUNC_SPI);
+  // gpio_set_function(PIN_SCK, GPIO_FUNC_SPI);
+  // gpio_set_function(PIN_RX, GPIO_FUNC_SPI);
+  // gpio_set_function(PIN_TX, GPIO_FUNC_SPI);
+
+  // hook up our (one?) interrupt... 
+  // NOTE: changing SPI_INST requires hard-coded change here 
+  // irq_set_exclusive_handler(SPI1_IRQ, spipi_irq_handler);
+}
+
+
+// void spipi_irq_handler(void){
+//   // both have up to 8 bytes to read / write per interrupt ? 
+//   // get bytes while readable, 
+//   if(spi_is_readable(SPI_INST)){
+//     uint8_t byte = SPI_HW->dr;
+//   }
+//   // write bytes while writable 
+//   if(spi_is_writable(SPI_INST)){
+//     SPI_HW->dr = 85;
+//   }
+//   // if we're out of data, we could turn interrupts off w/ this:
+//   // i.e. *just* turning the RX-interrupt on... ?? 
+//   SPI_HW->imsc = 0 | SPI_IMSC_RXIM_ON;
+// }
diff --git a/rpi_spi/code/spi_peripheral_bare/spipi.h b/rpi_spi/code/spi_peripheral_bare/spipi.h
new file mode 100644
index 0000000000000000000000000000000000000000..6c9791583cd0503d421eca880b589022393b3808
--- /dev/null
+++ b/rpi_spi/code/spi_peripheral_bare/spipi.h
@@ -0,0 +1,9 @@
+#ifndef SPI_PI_H_
+#define SPI_PI_H_
+
+#include <Arduino.h>
+
+void spipi_begin(void);
+uint32_t spipi_get_events(void);
+
+#endif 
\ No newline at end of file