diff --git a/components/badge23/CMakeLists.txt b/components/badge23/CMakeLists.txt
index ad46a42657c98be4b317a9e471730ff4582a302b..f24ac11a72c2a69fe7d5bef44f8bf8beb4ee8f32 100644
--- a/components/badge23/CMakeLists.txt
+++ b/components/badge23/CMakeLists.txt
@@ -3,7 +3,6 @@ idf_component_register(
         captouch.c
         espan.c
         spio.c
-        leds.c
     INCLUDE_DIRS
         include
     REQUIRES
diff --git a/components/badge23/espan.c b/components/badge23/espan.c
index ad1de44577daf26efd60cacf7bd639077366821c..9185c99fefd34735f88e105d5a40b05f5427b52e 100644
--- a/components/badge23/espan.c
+++ b/components/badge23/espan.c
@@ -1,5 +1,4 @@
 #include "badge23/captouch.h"
-#include "badge23/leds.h"
 #include "badge23/spio.h"
 #include "badge23/lock.h"
 
@@ -7,6 +6,7 @@
 #include "st3m_gfx.h"
 #include "st3m_fs.h"
 #include "st3m_audio.h"
+#include "st3m_leds.h"
 
 #include "bl00mbox.h"
 
@@ -39,7 +39,7 @@ static void io_slow_task(void * data){
     while(1) {
         vTaskDelayUntil(&last_wake, pdMS_TO_TICKS(100)); // 10 Hz
         st3m_audio_update_jacksense();
-        leds_update_hardware();
+        st3m_leds_update_hardware();
     }
 }
 
@@ -52,7 +52,6 @@ void badge23_main(void)
     locks_init();
     ESP_LOGI(TAG, "Starting on %s...", flow3r_bsp_hw_name);
 
-    leds_init();
     init_buttons();
     captouch_init();
     spio_badge_link_disable(255);
diff --git a/components/badge23/include/badge23/spio.h b/components/badge23/include/badge23/spio.h
index 3df9ab606d2e421821e1668b8f84d224f9f5720b..e12afbb207fac7654bb55fb81568e5acf9d311d9 100644
--- a/components/badge23/include/badge23/spio.h
+++ b/components/badge23/include/badge23/spio.h
@@ -1,5 +1,7 @@
 #pragma once
+
 #include <stdint.h>
+#include <stdbool.h>
 
 #define BUTTON_PRESSED_DOWN 2
 #define BUTTON_PRESSED_LEFT -1
diff --git a/components/st3m/CMakeLists.txt b/components/st3m/CMakeLists.txt
index 5091d6d4da0eb9df8ae357e9d5f4d1e923d8ee2b..07b44774eb8ea6659719057d4d65997c355d6eb5 100644
--- a/components/st3m/CMakeLists.txt
+++ b/components/st3m/CMakeLists.txt
@@ -6,6 +6,7 @@ idf_component_register(
         st3m_counter.c
         st3m_fs.c
         st3m_scope.c
+        st3m_leds.c
     INCLUDE_DIRS
         .
     REQUIRES
diff --git a/components/st3m/st3m_board_startup.c b/components/st3m/st3m_board_startup.c
index 3cf31df112ee65855f46d2b297dd9257caf9c551..f5c4bdb19dec58ed62fa02121294761e89716e65 100644
--- a/components/st3m/st3m_board_startup.c
+++ b/components/st3m/st3m_board_startup.c
@@ -2,6 +2,8 @@
 #include "st3m_fs.h"
 #include "st3m_audio.h"
 #include "st3m_scope.h"
+#include "st3m_leds.h"
+
 #include "flow3r_bsp.h"
 
 // Declared by badge23 codebase. To be removed and slurped up into st3m.
@@ -23,6 +25,7 @@ void st3m_board_startup(void) {
     st3m_fs_init();
     st3m_scope_init();
     st3m_audio_init();
+    st3m_leds_init();
 
     // Handoff to badge23.
     badge23_main();
diff --git a/components/badge23/leds.c b/components/st3m/st3m_leds.c
similarity index 79%
rename from components/badge23/leds.c
rename to components/st3m/st3m_leds.c
index 438f75ff84260cc4b0f74167698b13e6054de40f..0b46cbfa437a68bddd6cdbb0adf25dcf51ace523 100644
--- a/components/badge23/leds.c
+++ b/components/st3m/st3m_leds.c
@@ -1,17 +1,17 @@
 #include <freertos/FreeRTOS.h>
 #include <freertos/task.h>
-#include <freertos/queue.h>
+#include <freertos/semphr.h>
 #include <stdio.h>
 #include <string.h>
 #include <math.h>
 #include "esp_system.h"
-#include "badge23/leds.h"
-#include "badge23/lock.h"
 
 #include "flow3r_bsp.h"
+#include "st3m_leds.h"
+
 #include "esp_log.h"
 
-static const char *TAG = "badge23-leds";
+static const char *TAG = "st3m-leds";
 
 static uint8_t leds_brightness = 69;;
 static uint8_t leds_slew_rate = 255;
@@ -38,9 +38,13 @@ struct RGB
     unsigned char B;
 };
 
-struct RGB led_target[40] = {0,};
-struct RGB led_target_buffer[40] = {0,};
-struct RGB led_hardware_value[40] = {0,};
+static struct RGB led_target[40] = {0,};
+static struct RGB led_target_buffer[40] = {0,};
+static struct RGB led_hardware_value[40] = {0,};
+
+SemaphoreHandle_t mutex;
+#define LOCK xSemaphoreTake(mutex, portMAX_DELAY)
+#define UNLOCK xSemaphoreGive(mutex)
 
 struct HSV
 {
@@ -49,7 +53,7 @@ struct HSV
     double V;
 };
 
-struct RGB HSVToRGB(struct HSV hsv) {
+static struct RGB HSVToRGB(struct HSV hsv) {
     double r = 0, g = 0, b = 0;
 
     if (hsv.S == 0)
@@ -124,7 +128,7 @@ struct RGB HSVToRGB(struct HSV hsv) {
     return rgb;
 }
 
-void set_single_led(uint8_t index, uint8_t c[3]){
+static void set_single_led(uint8_t index, uint8_t c[3]){
     index = ((39-index) + 1 + 32)%40;
     flow3r_bsp_leds_set_pixel(index, c[0], c[1], c[2]);
 }
@@ -158,9 +162,9 @@ static void leds_update_target(){
     }
 }
 
-void leds_update_hardware(){ 
+void st3m_leds_update_hardware(){ 
     if(leds_auto_update) leds_update_target();
-    xSemaphoreTake(mutex_LED, portMAX_DELAY);
+    LOCK;
     for(int i = 0; i < 40; i++){
         uint8_t c[3];
         c[0] = led_target[i].R * leds_brightness/255;
@@ -179,16 +183,16 @@ void leds_update_hardware(){
         set_single_led(index, c);
     }
     renderLEDs();
-    xSemaphoreGive(mutex_LED);
+    UNLOCK;
 }
 
-void leds_set_single_rgb(uint8_t index, uint8_t red, uint8_t green, uint8_t blue){
+void st3m_leds_set_single_rgb(uint8_t index, uint8_t red, uint8_t green, uint8_t blue){
     led_target_buffer[index].R = red;
     led_target_buffer[index].G = green;
     led_target_buffer[index].B = blue;
 }
  
-void leds_set_single_hsv(uint8_t index, float hue, float sat, float val){
+void st3m_leds_set_single_hsv(uint8_t index, float hue, float sat, float val){
     struct RGB rgb;
     struct HSV hsv;
     hsv.H = hue;
@@ -202,24 +206,27 @@ void leds_set_single_hsv(uint8_t index, float hue, float sat, float val){
     led_target_buffer[index].B = rgb.B;
 }
 
-void leds_set_all_rgb(uint8_t red, uint8_t green, uint8_t blue){
+void st3m_leds_set_all_rgb(uint8_t red, uint8_t green, uint8_t blue){
     for(int i = 0; i<40; i++){
-        leds_set_single_rgb(i, red, green, blue);
+        st3m_leds_set_single_rgb(i, red, green, blue);
     }
 }
 
-void leds_set_all_hsv(float h, float s, float v){
+void st3m_leds_set_all_hsv(float h, float s, float v){
     for(int i = 0; i<40; i++){
-        leds_set_single_hsv(i, h, s, v);
+        st3m_leds_set_single_hsv(i, h, s, v);
     }
 }
 
-void leds_update(){
+void st3m_leds_update(){
     leds_update_target();
-    leds_update_hardware();
+    st3m_leds_update_hardware();
 }
 
-void leds_init(){
+void st3m_leds_init(){
+    mutex = xSemaphoreCreateMutex();
+    assert(mutex != NULL);
+
     for(uint16_t i = 0; i<256; i++){
         gamma_red[i] = i;
         gamma_green[i] = i;
@@ -235,31 +242,31 @@ void leds_init(){
     ESP_LOGI(TAG, "LEDs initialized");
 }
 
-void leds_set_brightness(uint8_t b){
+void st3m_leds_set_brightness(uint8_t b){
     leds_brightness = b;
 }
 
-uint8_t leds_get_brightness(){
+uint8_t st3m_leds_get_brightness(){
     return leds_brightness;
 }
 
-void leds_set_slew_rate(uint8_t s){
+void st3m_leds_set_slew_rate(uint8_t s){
     leds_slew_rate = s;
 }
 
-uint8_t leds_get_slew_rate(){
+uint8_t st3m_leds_get_slew_rate(){
     return leds_slew_rate;
 }
 
-void leds_set_auto_update(bool on){
+void st3m_leds_set_auto_update(bool on){
     leds_auto_update = on;
 }
 
-bool leds_get_auto_update(){
+bool st3m_leds_get_auto_update(){
     return leds_auto_update;
 }
 
-void leds_set_gamma(float red, float green, float blue){
+void st3m_leds_set_gamma(float red, float green, float blue){
     for(uint16_t i = 0; i<256; i++){
         if(i == 0){
             gamma_red[i] = 0;
diff --git a/components/badge23/include/badge23/leds.h b/components/st3m/st3m_leds.h
similarity index 54%
rename from components/badge23/include/badge23/leds.h
rename to components/st3m/st3m_leds.h
index d1023673f9026e4a493ad177ff6abf7f665a80bd..63df848d49456e973e362a3e8732972cf3da097d 100644
--- a/components/badge23/include/badge23/leds.h
+++ b/components/st3m/st3m_leds.h
@@ -5,42 +5,42 @@
 
 /* inits stuff ig
  */
-void leds_init();
+void st3m_leds_init();
 
 /* Set a single/all LEDs to change color with the next (auto) update. Index starts above
  * USB-C port and increments ccw. There are 8 LEDs per top petal.
  */
-void leds_set_single_rgb(uint8_t index, uint8_t red, uint8_t green, uint8_t blue);
-void leds_set_single_hsv(uint8_t index, float hue, float sat, float value);
-void leds_set_all_rgb(uint8_t red, uint8_t green, uint8_t blue);
-void leds_set_all_hsv(float hue, float sat, float value);
+void st3m_leds_set_single_rgb(uint8_t index, uint8_t red, uint8_t green, uint8_t blue);
+void st3m_leds_set_single_hsv(uint8_t index, float hue, float sat, float value);
+void st3m_leds_set_all_rgb(uint8_t red, uint8_t green, uint8_t blue);
+void st3m_leds_set_all_hsv(float hue, float sat, float value);
 
 /* Set/get global LED brightness. Default 69.
  */
-void leds_set_brightness(uint8_t brightness);
-uint8_t leds_get_brightness();
+void st3m_leds_set_brightness(uint8_t brightness);
+uint8_t st3m_leds_get_brightness();
 
 /* Set/get maximum change rate of brightness. Set to 1-3 for fade effects, set to
  * 255 to disable. Currently clocks at 10Hz.
  */
-void leds_set_slew_rate(uint8_t slew_rate);
-uint8_t leds_get_slew_rate();
+void st3m_leds_set_slew_rate(uint8_t slew_rate);
+uint8_t st3m_leds_get_slew_rate();
 
 /* Update LEDs. 
  */
-void leds_update();
+void st3m_leds_update();
 
 /* Used internally for slew rate animation loop.
  */
-void leds_update_hardware(); 
+void st3m_leds_update_hardware(); 
 
 /* Bend the rgb curves with an exponent each. (1,1,1) is default, (2,2,2) works well too
  * If someone wants to do color calibration, this is ur friend
  */
-void leds_set_gamma(float red, float green, float blue); 
+void st3m_leds_set_gamma(float red, float green, float blue); 
 
 /* leds_update is periodically called by the background task for slew rate animation when
  * set to 1. This adds user changes immediately. Useful with low slew rates.
  */
-void leds_set_auto_update(bool on);
-bool leds_get_auto_update();
+void st3m_leds_set_auto_update(bool on);
+bool st3m_leds_get_auto_update();
diff --git a/usermodule/mp_badge_link.c b/usermodule/mp_badge_link.c
index 157ba401d6d452f39d44c1a668ab5bbbe12b38c5..237bd9bf9ba29ec5ab081b9566a8853f51b2764d 100644
--- a/usermodule/mp_badge_link.c
+++ b/usermodule/mp_badge_link.c
@@ -11,7 +11,6 @@
 #include "py/builtin.h"
 #include "py/runtime.h"
 
-#include "badge23/leds.h"
 #include "badge23/captouch.h"
 #include "badge23/spio.h"
 #include "badge23/espan.h"
diff --git a/usermodule/mp_leds.c b/usermodule/mp_leds.c
index 8f7e35a711446d8a8052ee784303a42e149dfee3..ad4e2008b73d86054e7cc0a6376c90fa9b1d6931 100644
--- a/usermodule/mp_leds.c
+++ b/usermodule/mp_leds.c
@@ -11,45 +11,44 @@
 #include "py/builtin.h"
 #include "py/runtime.h"
 
-#include "badge23/leds.h"
-#include "badge23/espan.h"
+#include "st3m_leds.h"
 
 STATIC mp_obj_t mp_leds_set_brightness(mp_obj_t b) {
-    leds_set_brightness(mp_obj_get_int(b));
+    st3m_leds_set_brightness(mp_obj_get_int(b));
     return mp_const_none;
 }
 STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_leds_set_brightness_obj, mp_leds_set_brightness);
 
 STATIC mp_obj_t mp_leds_get_brightness() {
-    return mp_obj_new_int(leds_get_brightness());
+    return mp_obj_new_int(st3m_leds_get_brightness());
 }
 STATIC MP_DEFINE_CONST_FUN_OBJ_0(mp_leds_get_brightness_obj, mp_leds_get_brightness);
 
 STATIC mp_obj_t mp_leds_set_auto_update(mp_obj_t on) {
-    leds_set_auto_update(mp_obj_get_int(on));
+    st3m_leds_set_auto_update(mp_obj_get_int(on));
     return mp_const_none;
 }
 STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_leds_set_auto_update_obj, mp_leds_set_auto_update);
 
 STATIC mp_obj_t mp_leds_get_auto_update() {
-    return mp_obj_new_int(leds_get_auto_update());
+    return mp_obj_new_int(st3m_leds_get_auto_update());
 }
 STATIC MP_DEFINE_CONST_FUN_OBJ_0(mp_leds_get_auto_update_obj, mp_leds_get_auto_update);
 
 STATIC mp_obj_t mp_leds_set_gamma(mp_obj_t r, mp_obj_t g, mp_obj_t b) {
-    leds_set_gamma(mp_obj_get_float(r), mp_obj_get_float(g), mp_obj_get_float(b));
+    st3m_leds_set_gamma(mp_obj_get_float(r), mp_obj_get_float(g), mp_obj_get_float(b));
     return mp_const_none;
 }
 STATIC MP_DEFINE_CONST_FUN_OBJ_3(mp_leds_set_gamma_obj, mp_leds_set_gamma);
 
 STATIC mp_obj_t mp_leds_set_slew_rate(mp_obj_t b) {
-    leds_set_slew_rate(mp_obj_get_int(b));
+    st3m_leds_set_slew_rate(mp_obj_get_int(b));
     return mp_const_none;
 }
 STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_leds_set_slew_rate_obj, mp_leds_set_slew_rate);
 
 STATIC mp_obj_t mp_leds_get_slew_rate() {
-    return mp_obj_new_int(leds_get_slew_rate());
+    return mp_obj_new_int(st3m_leds_get_slew_rate());
 }
 STATIC MP_DEFINE_CONST_FUN_OBJ_0(mp_leds_get_slew_rate_obj, mp_leds_get_slew_rate);
 
@@ -58,7 +57,7 @@ STATIC mp_obj_t mp_led_set_rgb(size_t n_args, const mp_obj_t *args) {
     uint8_t red =  mp_obj_get_int(args[1]);
     uint8_t green =  mp_obj_get_int(args[2]);
     uint8_t blue =  mp_obj_get_int(args[3]);
-    leds_set_single_rgb(index, red, green, blue);
+    st3m_leds_set_single_rgb(index, red, green, blue);
     return mp_const_none;
 }
 STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_led_set_rgb_obj, 4, 4, mp_led_set_rgb);
@@ -68,7 +67,7 @@ STATIC mp_obj_t mp_led_set_hsv(size_t n_args, const mp_obj_t *args) {
     float hue =  mp_obj_get_float(args[1]);
     float sat =  mp_obj_get_float(args[2]);
     float val =  mp_obj_get_float(args[3]);
-    leds_set_single_hsv(index, hue, sat, val);
+    st3m_leds_set_single_hsv(index, hue, sat, val);
     return mp_const_none;
 }
 STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_led_set_hsv_obj,4,4, mp_led_set_hsv);
@@ -77,7 +76,7 @@ STATIC mp_obj_t mp_led_set_all_rgb(mp_obj_t r, mp_obj_t g, mp_obj_t b) {
     uint8_t red =  mp_obj_get_int(r);
     uint8_t green =  mp_obj_get_int(g);
     uint8_t blue =  mp_obj_get_int(b);
-    leds_set_all_rgb(red, green, blue);
+    st3m_leds_set_all_rgb(red, green, blue);
     return mp_const_none;
 }
 STATIC MP_DEFINE_CONST_FUN_OBJ_3(mp_led_set_all_rgb_obj, mp_led_set_all_rgb);
@@ -86,13 +85,13 @@ STATIC mp_obj_t mp_led_set_all_hsv(mp_obj_t h, mp_obj_t s, mp_obj_t v) {
     float hue =  mp_obj_get_float(h);
     float sat =  mp_obj_get_float(s);
     float val =  mp_obj_get_float(v);
-    leds_set_all_hsv(hue, sat, val);
+    st3m_leds_set_all_hsv(hue, sat, val);
     return mp_const_none;
 }
 STATIC MP_DEFINE_CONST_FUN_OBJ_3(mp_led_set_all_hsv_obj, mp_led_set_all_hsv);
 
 STATIC mp_obj_t mp_leds_update() {
-    leds_update();
+    st3m_leds_update();
     return mp_const_none;
 }
 STATIC MP_DEFINE_CONST_FUN_OBJ_0(mp_leds_update_obj, mp_leds_update);