diff --git a/stmhal/Makefile b/stmhal/Makefile
index 56c00e905a7ad3612ee9ba39a8faabd2e0d78758..ac0367024aee82e833a2625184578afbf58fee45 100644
--- a/stmhal/Makefile
+++ b/stmhal/Makefile
@@ -71,7 +71,6 @@ SRC_C = \
 	printf.c \
 	math.c \
 	mathsincos.c \
-	malloc0.c \
 	gccollect.c \
 	pybstdio.c \
 	readline.c \
diff --git a/stmhal/main.c b/stmhal/main.c
index c5633fb68ba16aa22638b7606f1acda5e042814c..2d7e76172f0dc1c153378637098eae8f6650eebb 100644
--- a/stmhal/main.c
+++ b/stmhal/main.c
@@ -1,9 +1,7 @@
 #include <stdio.h>
 #include <string.h>
 
-#include <stm32f4xx_hal.h>
-#include <stm32f4xx_hal_gpio.h>
-#include "std.h"
+#include "stm32f4xx_hal.h"
 
 #include "misc.h"
 #include "systick.h"
@@ -14,11 +12,10 @@
 #include "lexer.h"
 #include "parse.h"
 #include "obj.h"
-#include "parsehelper.h"
-#include "compile.h"
 #include "runtime.h"
 #include "gc.h"
 #include "gccollect.h"
+#include "pybstdio.h"
 #include "readline.h"
 #include "pyexec.h"
 #include "usart.h"
@@ -64,12 +61,25 @@ void flash_error(int n) {
 }
 
 void __fatal_error(const char *msg) {
-#if MICROPY_HW_HAS_LCD
+    for (volatile uint delay = 0; delay < 10000000; delay++) {
+    }
+    led_state(1, 1);
+    led_state(2, 1);
+    led_state(3, 1);
+    led_state(4, 1);
+    stdout_tx_strn("\nFATAL ERROR:\n", 14);
+    stdout_tx_strn(msg, strlen(msg));
+#if 0 && MICROPY_HW_HAS_LCD
     lcd_print_strn("\nFATAL ERROR:\n", 14);
     lcd_print_strn(msg, strlen(msg));
 #endif
-    for (;;) {
-        flash_error(1);
+    for (uint i = 0;;) {
+        led_toggle(((i++) & 3) + 1);
+        for (volatile uint delay = 0; delay < 10000000; delay++) {
+        }
+        if (i >= 8) {
+            __WFI();
+        }
     }
 }
 
@@ -109,16 +119,6 @@ STATIC mp_obj_t pyb_usb_mode(mp_obj_t usb_mode) {
 
 MP_DEFINE_CONST_FUN_OBJ_1(pyb_usb_mode_obj, pyb_usb_mode);
 
-void fatality(void) {
-    led_state(PYB_LED_R1, 1);
-    led_state(PYB_LED_G1, 1);
-    led_state(PYB_LED_R2, 1);
-    led_state(PYB_LED_G2, 1);
-    for (;;) {
-        flash_error(1);
-    }
-}
-
 static const char fresh_boot_py[] =
 "# boot.py -- run on boot-up\n"
 "# can run arbitrary Python, but best to keep it minimal\n"
diff --git a/stmhal/malloc0.c b/stmhal/malloc0.c
deleted file mode 100644
index 510fa0d740cac77abd6207df157034ff67016402..0000000000000000000000000000000000000000
--- a/stmhal/malloc0.c
+++ /dev/null
@@ -1,37 +0,0 @@
-#include <stdio.h>
-#include <stdint.h>
-#include "misc.h"
-#include "mpconfig.h"
-#include "gc.h"
-
-#if 0
-static uint32_t mem = 0;
-
-void *malloc(size_t n) {
-    if (mem == 0) {
-        extern uint32_t _heap_start;
-        mem = (uint32_t)&_heap_start; // need to use big ram block so we can execute code from it (is it true that we can't execute from CCM?)
-    }
-    void *ptr = (void*)mem;
-    mem = (mem + n + 3) & (~3);
-    if (mem > 0x20000000 + 0x18000) {
-        void __fatal_error(const char*);
-        __fatal_error("out of memory");
-    }
-    return ptr;
-}
-
-void free(void *ptr) {
-}
-
-void *realloc(void *ptr, size_t n) {
-    return malloc(n);
-}
-
-#endif
-
-void __assert_func(void) {
-    printf("\nASSERT FAIL!");
-    for (;;) {
-    }
-}
diff --git a/stmhal/std.h b/stmhal/std.h
index 843ddd827098539c81f44ab2203165bbf0f5c848..6982b715d0edb367b48b8194c409f84e9c392673 100644
--- a/stmhal/std.h
+++ b/stmhal/std.h
@@ -1,7 +1,5 @@
 typedef unsigned int size_t;
 
-void __assert_func(void);
-
 void *memcpy(void *dest, const void *src, size_t n);
 void *memmove(void *dest, const void *src, size_t n);
 void *memset(void *s, int c, size_t n);
diff --git a/stmhal/stm32f4xx_it.c b/stmhal/stm32f4xx_it.c
index 06428a4c4fad37c3e6516c5ea793b29bc173da48..df69f52b8e5298a5f53ecb4fb203c5919c26a257 100644
--- a/stmhal/stm32f4xx_it.c
+++ b/stmhal/stm32f4xx_it.c
@@ -64,7 +64,7 @@
 /* Private macro -------------------------------------------------------------*/
 /* Private variables ---------------------------------------------------------*/
 
-extern void fatality();
+extern void __fatal_error(const char*);
 extern PCD_HandleTypeDef hpcd;
 
 /* Private function prototypes -----------------------------------------------*/
@@ -88,12 +88,10 @@ void NMI_Handler(void)
   * @param  None
   * @retval None
   */
-void HardFault_Handler(void)
-{
+void HardFault_Handler(void) {
   /* Go to infinite loop when Hard Fault exception occurs */
-  while (1)
-  {
-    fatality();
+  while (1) {
+    __fatal_error("HardFault");
   }
 }
 
@@ -102,12 +100,10 @@ void HardFault_Handler(void)
   * @param  None
   * @retval None
   */
-void MemManage_Handler(void)
-{
+void MemManage_Handler(void) {
   /* Go to infinite loop when Memory Manage exception occurs */
-  while (1)
-  {
-    fatality();
+  while (1) {
+    __fatal_error("MemManage");
   }
 }
 
@@ -116,12 +112,10 @@ void MemManage_Handler(void)
   * @param  None
   * @retval None
   */
-void BusFault_Handler(void)
-{
+void BusFault_Handler(void) {
   /* Go to infinite loop when Bus Fault exception occurs */
-  while (1)
-  {
-    fatality();
+  while (1) {
+    __fatal_error("BusFault");
   }
 }
 
@@ -130,12 +124,10 @@ void BusFault_Handler(void)
   * @param  None
   * @retval None
   */
-void UsageFault_Handler(void)
-{
+void UsageFault_Handler(void) {
   /* Go to infinite loop when Usage Fault exception occurs */
-  while (1)
-  {
-    fatality();
+  while (1) {
+    __fatal_error("UsageFault");
   }
 }