From f565f3e6c71b30ff29cb6bdcfb3f9ec9c0f51dc4 Mon Sep 17 00:00:00 2001
From: Rahix <rahix@rahix.de>
Date: Wed, 13 Nov 2019 14:11:33 +0100
Subject: [PATCH] feat(panic): Display panic message on the display

Currently, panics will silently reboot if the user doesn't happen to
look at the serial console when it happens.  To give a bit more
feedback, display @msgctl's faultsplash and the panic messages as well.

Co-authored-by: Mateusz Zalega <mateusz@appliedsourcery.com>
Signed-off-by: Rahix <rahix@rahix.de>
---
 epicardium/modules/panic.c | 78 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 78 insertions(+)

diff --git a/epicardium/modules/panic.c b/epicardium/modules/panic.c
index aa27b4de5..ce1e1b0f6 100644
--- a/epicardium/modules/panic.c
+++ b/epicardium/modules/panic.c
@@ -15,9 +15,15 @@
 #include "card10.h"
 #include "card10-version.h"
 
+#include "gfx.h"
+#include "display.h"
+#include "LCD_Driver.h"
+
 #include <stdio.h>
 #include <stdarg.h>
 
+static void faultsplash(const char *msg);
+
 void __attribute__((noreturn)) panic(const char *format, ...)
 {
 	/* Turn off interrupts.  We won't get back from here anyway. */
@@ -55,6 +61,12 @@ void __attribute__((noreturn)) panic(const char *format, ...)
 	       "\x1b[0m -> https://git.card10.badge.events.ccc.de/card10/firmware/issues/new?issue <-\n"
 	       "\x1b[31m           --- ====== ===== ---\x1b[0m\n");
 
+	char faultsplash_buffer[14 * 4];
+	va_start(ap, format);
+	vsnprintf(faultsplash_buffer, sizeof(faultsplash_buffer), format, ap);
+	va_end(ap);
+	faultsplash(faultsplash_buffer);
+
 	for (int i = 0; i < 96000000; i++) {
 		__asm volatile("nop");
 	}
@@ -74,3 +86,69 @@ void __attribute__((noreturn)) __assert_func(
 	      line,
 	      func);
 }
+
+static const unsigned char faultsplash_rle[] = {
+	0x7f, 0x50, 0x83, 0x0f, 0x82, 0x7f, 0x0d, 0x83, 0x0f, 0x82, 0x7f, 0x1d,
+	0x82, 0x7f, 0x1f, 0x82, 0x7f, 0x1f, 0x82, 0x7f, 0x12, 0x82, 0x09, 0x82,
+	0x7f, 0x14, 0x82, 0x09, 0x82, 0x7f, 0x09, 0x82, 0x11, 0x83, 0x7f, 0x0b,
+	0x82, 0x11, 0x83, 0x7f, 0x0f, 0x82, 0x07, 0x82, 0x7f, 0x16, 0x82, 0x07,
+	0x82, 0x7f, 0x16, 0x82, 0x07, 0x82, 0x7f, 0x1a, 0x83, 0x7f, 0x1e, 0x83,
+	0x7f, 0x0a, 0x8b, 0x17, 0x82, 0x02, 0x82, 0x02, 0x83, 0x73, 0x8c, 0x16,
+	0x82, 0x02, 0x82, 0x02, 0x83, 0x72, 0x81, 0x0c, 0x84, 0x07, 0x85, 0x7f,
+	0x03, 0x82, 0x0c, 0x84, 0x07, 0x86, 0x7f, 0x02, 0x82, 0x0c, 0x84, 0x07,
+	0x86, 0x7f, 0x82, 0x12, 0x87, 0x7f, 0x06, 0x82, 0x12, 0x87, 0x7f, 0x06,
+	0x82, 0x24, 0x82, 0x78, 0x82, 0x24, 0x82, 0x78, 0x82, 0x24, 0x82, 0x78,
+	0x82, 0x16, 0x83, 0x04, 0x82, 0x07, 0x82, 0x76, 0x82, 0x16, 0x83, 0x04,
+	0x82, 0x07, 0x82, 0x70, 0x8f, 0x0d, 0x82, 0x12, 0x82, 0x6e, 0x8f, 0x0d,
+	0x82, 0x12, 0x82, 0x6e, 0x8f, 0x0b, 0x82, 0x09, 0x82, 0x0b, 0x82, 0x6c,
+	0x8f, 0x0b, 0x82, 0x09, 0x82, 0x0b, 0x82, 0x6c, 0x8f, 0x0b, 0x82, 0x09,
+	0x82, 0x0b, 0x82, 0x6c, 0x8f, 0x7f, 0x12, 0x8f, 0x7f, 0x0d, 0x98, 0x12,
+	0x82, 0x74, 0x98, 0x12, 0x82, 0x70, 0xa1, 0x7f, 0xa1, 0x7f, 0xa1, 0x7f,
+	0xa1, 0x7f, 0xa1, 0x7d, 0xa5, 0x7b, 0xa5, 0x7b, 0xa5, 0x7b, 0xa5, 0x7a,
+	0xa6, 0x78, 0x89, 0x02, 0x9f, 0x76, 0x89, 0x02, 0x9f, 0x76, 0xaa, 0x76,
+	0xaa, 0x76, 0x87, 0x02, 0xa1, 0x76, 0x87, 0x02, 0xa1, 0x76, 0x87, 0x02,
+	0xa1, 0x76, 0x87, 0x02, 0xa1, 0x76, 0x87, 0x02, 0xa1, 0x76, 0x87, 0x02,
+	0xa1, 0x76, 0x87, 0x02, 0xa1, 0x76, 0xaa, 0x76, 0xaa, 0x76, 0xaa, 0x76,
+	0x89, 0x02, 0x9f, 0x76, 0x89, 0x02, 0x9f, 0x79, 0xa5, 0x7b, 0xa5, 0x7b,
+	0xa5, 0x7b, 0x8b, 0x02, 0x98, 0x7b, 0x8b, 0x02, 0x98, 0x7d, 0xa1, 0x7f,
+	0xa1, 0x7f, 0xa1, 0x7f, 0xa1, 0x7f, 0xa1, 0x7f, 0x04, 0x98, 0x7f, 0x09,
+	0x98, 0x7f, 0x0e, 0x8f, 0x7f, 0x12, 0x8f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+	0x7f, 0x06
+};
+
+static void faultsplash(const char *msg)
+{
+	LCD_SetBacklight(100);
+
+	gfx_copy_region(
+		&display_screen,
+		0,
+		0,
+		160,
+		80,
+		GFX_RLE_MONO,
+		sizeof(faultsplash_rle),
+		faultsplash_rle
+	);
+
+	gfx_puts(&Font20, &display_screen, 80, 5, "Panic", 0xf800, 0xf800);
+
+	size_t len   = strlen(msg);
+	char buf[15] = { 0 };
+	int offset   = 34;
+	for (size_t i = 0; i < len; i += 14) {
+		strncpy(buf, &msg[i], 14);
+		gfx_puts(
+			&Font12,
+			&display_screen,
+			52,
+			offset,
+			buf,
+			0xc618,
+			0xc618
+		);
+		offset += 12;
+	}
+
+	gfx_update(&display_screen);
+}
-- 
GitLab