leddie/firmware/lib/system.c
Markus Koch d91fe6787c fw: Add watchdog
Will reset after 1 second spent in app mainloop.
2024-09-22 10:52:05 +02:00

92 lines
1.5 KiB
C

#include <avr/io.h>
#include <avr/wdt.h>
#include <util/delay.h>
#include <string.h>
#include <stdlib.h>
#include "system.h"
#include "pm.h"
extern void app_init();
extern void app_suspend();
extern enum app_return app_mainloop();
struct cRGB led[STRIPLEN];
void display_update() {
ws2812_setleds(led, STRIPLEN);
}
void display_clear() {
memset(led, 0, STRIPLEN * 3);
}
void system_init()
{
pm_disable_periphery();
button_init();
TIFR = 0xFF; // Clear all interrupt flags
pm_init();
pm_axl_on();
_delay_ms(50);
mma8653_init();
while (HAL_ASSERTED_N(BUTTON_N)) // Prevent boot while button is pressed
_delay_ms(25);
timers_init();
}
enum BOOT_COLOR {RED, BLUE, GREEN};
void boot_animation(enum BOOT_COLOR color_offset)
{
_delay_ms(10);
display_clear();
for(int i = 0; i<STRIPLEN; ++i) {
wdt_reset();
*(&led[i].r + color_offset) = 0x10;
display_update();
_delay_ms(15);
*(&led[i].r + color_offset) = 0x0;
}
display_update();
_delay_ms(10);
}
void system_boot()
{
system_init();
pm_led_on_auto();
boot_animation(GREEN);
app_init();
}
void system_suspend()
{
app_suspend();
boot_animation(RED);
pm_suspend();
}
int main()
{
enum app_return ar;
wdt_enable(WDTO_1S);
while (1) {
system_boot();
while ((ar = app_mainloop()) == RUN) {
wdt_reset();
}
// TODO: Handle reset instead of suspend
system_suspend();
}
pm_reset();
}
void systick_cb()
{
pm_led_on_auto(); // Turn off LED DC-DC converter when USB power is connected
button_systick_cb();
}