Skip to content
Snippets Groups Projects
Select Git revision
  • de7c425139c92745280b62f7ebb756def96d072a
  • wip-bootstrap default
  • dualcore
  • ch3/leds
  • ch3/time
  • master
6 results

objfun.c

Blame
  • panic.c 4.50 KiB
    /*
     * Panic
     * =====
     *
     * Under some conditions the firmware should crash and reboot automatically.
     * This module provides the necessary facilities to do so.
     *
     * Note that a panic should indicate **only** logic-errors in the firmware or
     * unrecoverable hardware conditions.
     */
    
    #include "modules/log.h"
    #include "modules/modules.h"
    
    #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. */
    	__asm volatile("cpsid	i" ::: "memory");
    
    	/*
    	 * Turn off asynchronous printing because that won't ever work from
    	 * here ...
    	 */
    	serial_return_to_synchronous();
    
    	printf("\x1b[31;1m           --- SYSTEM PANIC ---\n"
    	       "\x1b[0;31m         ---                  ---\n"
    	       "       ---                      ---\n"
    	       "\x1b[0m A fatal error occured:\n     \x1b[1m");
    
    	va_list ap;
    	va_start(ap, format);
    	vprintf(format, ap);
    	va_end(ap);
    
    	printf("\n"
    	       "\x1b[0m\n"
    	       " Firmware Version:\n"
    	       "\x1b[35m     %s\n",
    	       CARD10_VERSION);
    
    	printf("\x1b[0m\n"
    	       " Stack Trace:\n"
    	       "\x1b[36m     %p\n",
    	       __builtin_return_address(0));
    
    	printf("\x1b[33m\n"
    	       " Please report this error to the card10 firmware team!\n"
    	       "\x1b[0m -> https://git.card10.badge.events.ccc.de/card10/firmware/issues/new <-\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");
    	}
    
    	card10_reset();
    }
    
    void __attribute__((noreturn)) __assert_func(
    	const char *file, int line, const char *func, const char *failedexpr
    ) {
    	panic("Assertion failure:\n"
    	      "       \"%s\"\n"
    	      "       failed in \"%s:%d\",\n"
    	      "       function: %s()",
    	      failedexpr,
    	      file,
    	      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);
    }