diff --git a/epicardium/modules/panic.c b/epicardium/modules/panic.c index aa27b4de5ae7a856ed6beee6e8cc29cdab43e1bf..ce1e1b0f6191b2d696f35529bb943023e00e592e 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); +}