blob: c41afba69dc543cff2f1d7acf5d62325b187f2b3 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
|
/*
* Utility functions
*
* Copyright (C) 2009-2011 Michael Buesch <m@bues.ch>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include "util.h"
#include "main.h"
#include "debug.h"
#include "lcd.h"
#include "uart.h"
#include <avr/io.h>
#include <avr/wdt.h>
void long_delay_ms(uint16_t ms)
{
while (ms) {
_delay_ms(50);
wdt_reset();
ms = (ms >= 50) ? ms - 50 : 0;
}
}
char hexdigit_to_ascii(uint8_t digit)
{
/* Convert a hexadecimal digit (0-F) to an ASCII character */
if (digit >= 0xAu)
digit = (uint8_t)(digit + 0x41u - 0xAu);
else
digit = (uint8_t)(digit + 0x30u);
return (char)digit;
}
#ifndef BOOTLOADER
void do_panic(const char PROGPTR *msg)
{
irq_disable();
debug_printf("*** PANIC :( ***\n");
_debug_printf(msg);
debug_printf("\n");
lcd_clear_buffer();
lcd_printf("*** PANIC :( ***\n");
lcd_commit();
long_delay_ms(10000);
reboot();
}
void reboot(void)
{
irq_disable();
debug_printf("*** REBOOTING ***\n");
wdt_enable(WDTO_15MS);
while (1);
}
uint8_t ffs16(uint16_t value)
{
uint16_t mask;
uint8_t count;
for (mask = 1, count = 1; mask; mask <<= 1, count++) {
if (value & mask)
return count;
}
return 0;
}
#endif /* BOOTLOADER */
#ifdef STACKCHECK
/* Stack usage threshold, in percent of SRAM */
#define STACKTHRES 25
#define RAMSIZE (RAMEND - RAMSTART)
#define STACKLIM (RAMEND - ((uint32_t)RAMSIZE * STACKTHRES / 100))
static noinstrument void stack_check(void *this_fn,
void *call_site)
{
static bool had_overflow = 0;
uint16_t sp = SP;
if (sp >= STACKLIM)
return;
if (had_overflow)
return;
had_overflow = 1;
mb();
uart_putstr("WARNING: Stack size limit reached in 0x");
uart_puthex((uint16_t)this_fn >> 8);
uart_puthex((uint16_t)this_fn);
uart_putstr(" (called from 0x");
uart_puthex((uint16_t)call_site >> 8);
uart_puthex((uint16_t)call_site);
uart_putstr(")\n");
}
noinstrument noinline void __cyg_profile_func_enter(void *this_fn,
void *call_site)
{
stack_check(this_fn, call_site);
}
noinstrument noinline void __cyg_profile_func_exit(void *this_fn,
void *call_site)
{
}
#endif /* STACKCHECK */
|