diff --git a/stm/Makefile b/stm/Makefile
index d75c945bfc020a22da4d757adfcf0b12cae5d514..93e87ec4af602de8d24cb4549534983d1734d34f 100644
--- a/stm/Makefile
+++ b/stm/Makefile
@@ -36,6 +36,7 @@ SRC_C = \
 	sdio.c \
 	pybwlan.c \
 	i2c.c \
+	usrsw.c \
 
 SRC_S = \
 	startup_stm32f40xx.s \
diff --git a/stm/main.c b/stm/main.c
index 0ab44ca8d470a89fa29bb9b80f5407e3a3621830..f6aa42abf00dd658f490d939af42414157bb8cdd 100644
--- a/stm/main.c
+++ b/stm/main.c
@@ -39,6 +39,7 @@
 #include "audio.h"
 #include "pybwlan.h"
 #include "i2c.h"
+#include "usrsw.h"
 
 int errno;
 
@@ -73,52 +74,6 @@ static void impl02_c_version(void) {
     }
 }
 
-#define PYB_USRSW_PORT (GPIOA)
-#define PYB_USRSW_PIN (GPIO_Pin_13)
-
-void sw_init(void) {
-    // make it an input with pull-up
-    GPIO_InitTypeDef GPIO_InitStructure;
-    GPIO_InitStructure.GPIO_Pin = PYB_USRSW_PIN;
-    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
-    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
-    GPIO_Init(PYB_USRSW_PORT, &GPIO_InitStructure);
-
-    // the rest does the EXTI interrupt
-
-    /* Enable SYSCFG clock */
-    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
-
-    /* Connect EXTI Line13 to PA13 pin */
-    SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource13);
-
-    /* Configure EXTI Line13, rising edge */
-    EXTI_InitTypeDef EXTI_InitStructure;
-    EXTI_InitStructure.EXTI_Line = EXTI_Line13;
-    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
-    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
-    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
-    EXTI_Init(&EXTI_InitStructure);
-
-    /* Enable and set EXTI15_10 Interrupt to the lowest priority */
-    NVIC_InitTypeDef NVIC_InitStructure;
-    NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;
-    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;
-    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;
-    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
-    NVIC_Init(&NVIC_InitStructure);
-}
-
-int sw_get(void) {
-    if (PYB_USRSW_PORT->IDR & PYB_USRSW_PIN) {
-        // pulled high, so switch is not pressed
-        return 0;
-    } else {
-        // pulled low, so switch is pressed
-        return 1;
-    }
-}
-
 void __fatal_error(const char *msg) {
     lcd_print_strn("\nFATAL ERROR:\n", 14);
     lcd_print_strn(msg, strlen(msg));
@@ -156,14 +111,6 @@ mp_obj_t pyb_led(mp_obj_t state) {
     return state;
 }
 
-mp_obj_t pyb_sw(void) {
-    if (sw_get()) {
-        return mp_const_true;
-    } else {
-        return mp_const_false;
-    }
-}
-
 /*
 void g(uint i) {
     printf("g:%d\n", i);
diff --git a/stm/usrsw.c b/stm/usrsw.c
new file mode 100644
index 0000000000000000000000000000000000000000..e2565d0e0b9a8562e1783c8aea74c596a331ffec
--- /dev/null
+++ b/stm/usrsw.c
@@ -0,0 +1,69 @@
+#include <stm_misc.h>
+#include <stm32f4xx_gpio.h>
+#include <stm32f4xx_exti.h>
+#include <stm32f4xx_syscfg.h>
+#include <stm32f4xx_rcc.h>
+
+#include "misc.h"
+#include "mpconfig.h"
+#include "obj.h"
+#include "usrsw.h"
+
+#define PYB_USRSW_PORT (GPIOA)
+#define PYB_USRSW_PIN (GPIO_Pin_13)
+
+void sw_init(void) {
+    // make it an input with pull-up
+    GPIO_InitTypeDef GPIO_InitStructure;
+    GPIO_InitStructure.GPIO_Pin = PYB_USRSW_PIN;
+    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
+    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
+    GPIO_Init(PYB_USRSW_PORT, &GPIO_InitStructure);
+
+    // the rest does the EXTI interrupt
+
+    /* Enable SYSCFG clock */
+    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
+
+    /* Connect EXTI Line13 to PA13 pin */
+    SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource13);
+
+    /* Configure EXTI Line13, rising edge */
+    EXTI_InitTypeDef EXTI_InitStructure;
+    EXTI_InitStructure.EXTI_Line = EXTI_Line13;
+    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
+    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
+    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
+    EXTI_Init(&EXTI_InitStructure);
+
+    /* Enable and set EXTI15_10 Interrupt to the lowest priority */
+    NVIC_InitTypeDef NVIC_InitStructure;
+    NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;
+    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;
+    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;
+    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
+    NVIC_Init(&NVIC_InitStructure);
+}
+
+int sw_get(void) {
+    if (PYB_USRSW_PORT->IDR & PYB_USRSW_PIN) {
+        // pulled high, so switch is not pressed
+        return 0;
+    } else {
+        // pulled low, so switch is pressed
+        return 1;
+    }
+}
+
+/******************************************************************************/
+/* Micro Python bindings                                                      */
+
+mp_obj_t pyb_sw(void) {
+    if (sw_get()) {
+        return mp_const_true;
+    } else {
+        return mp_const_false;
+    }
+}
+
+
diff --git a/stm/usrsw.h b/stm/usrsw.h
new file mode 100644
index 0000000000000000000000000000000000000000..2833baaac7787141a60f4d2edb99db81479eced8
--- /dev/null
+++ b/stm/usrsw.h
@@ -0,0 +1,7 @@
+#ifndef __USRSW_H__
+#define __USRSW_H__
+void sw_init(void);
+int sw_get(void);
+
+mp_obj_t pyb_sw(void);
+#endif //__USRSW_H__