From bcb51a3ceabf3d86f627d87608b8d251a11c4904 Mon Sep 17 00:00:00 2001
From: Jeff Gough <gitlab@jeffreygough.com>
Date: Thu, 22 Aug 2019 16:04:17 +0000
Subject: [PATCH] feat(epicardium): Implement watchdog timer

---
 epicardium/main.c              |  3 +++
 epicardium/modules/hardware.c  | 18 ++++++++++++++++++
 epicardium/modules/meson.build |  1 +
 epicardium/modules/modules.h   |  3 +++
 epicardium/modules/watchdog.c  | 28 ++++++++++++++++++++++++++++
 5 files changed, 53 insertions(+)
 create mode 100644 epicardium/modules/watchdog.c

diff --git a/epicardium/main.c b/epicardium/main.c
index fba57b11..9f0e725b 100644
--- a/epicardium/main.c
+++ b/epicardium/main.c
@@ -104,6 +104,9 @@ int main(void)
 		abort();
 	}
 
+	/* Watchdog petting */
+	watchdog_clearer_init();
+
 	LOG_DEBUG("startup", "Starting FreeRTOS ...");
 	vTaskStartScheduler();
 
diff --git a/epicardium/modules/hardware.c b/epicardium/modules/hardware.c
index 01d76545..f7cca08d 100644
--- a/epicardium/modules/hardware.c
+++ b/epicardium/modules/hardware.c
@@ -20,6 +20,7 @@
 #include "rtc.h"
 #include "spi.h"
 #include "trng.h"
+#include "wdt.h"
 
 /*
  * Early init is called at the very beginning and is meant for modules which
@@ -28,6 +29,23 @@
  */
 int hardware_early_init(void)
 {
+	/*
+	 * Watchdog timer
+	 */
+	sys_cfg_wdt_t wdt_cfg = NULL;
+	WDT_Init(MXC_WDT0, wdt_cfg);
+
+	if (WDT_GetResetFlag(MXC_WDT0)) {
+		WDT_ClearResetFlag(MXC_WDT0);
+		LOG_INFO("watchdog", "Reset due to watchdog timeout");
+	}
+
+	WDT_Enable(MXC_WDT0, 1);
+	WDT_SetResetPeriod(
+		MXC_WDT0,
+		WDT_PERIOD_2_27); /* Clocked by PCLK at 50MHz, reset at 2^27 ticks = 2.7 seconds */
+	WDT_EnableReset(MXC_WDT0, 1);
+
 	/*
 	 * I2C bus for onboard peripherals (ie. PMIC, BMA400, BHI160, BME680,
 	 * ...)
diff --git a/epicardium/modules/meson.build b/epicardium/modules/meson.build
index dc231835..73975adc 100644
--- a/epicardium/modules/meson.build
+++ b/epicardium/modules/meson.build
@@ -18,4 +18,5 @@ module_sources = files(
   'stream.c',
   'trng.c',
   'vibra.c',
+  'watchdog.c',
 )
diff --git a/epicardium/modules/modules.h b/epicardium/modules/modules.h
index a6e2dd90..8760e691 100644
--- a/epicardium/modules/modules.h
+++ b/epicardium/modules/modules.h
@@ -35,6 +35,9 @@ int personal_state_enabled();
 /* ---------- PMIC --------------------------------------------------------- */
 void vPmicTask(void *pvParameters);
 
+/* ---------- Watchdog ----------------------------------------------------- */
+void watchdog_clearer_init();
+
 /* Critical battery voltage */
 #define BATTERY_CRITICAL   3.40f
 
diff --git a/epicardium/modules/watchdog.c b/epicardium/modules/watchdog.c
new file mode 100644
index 00000000..a538035d
--- /dev/null
+++ b/epicardium/modules/watchdog.c
@@ -0,0 +1,28 @@
+#include "modules/log.h"
+#include "modules/modules.h"
+
+#include "timers.h"
+#include "mxc_sys.h"
+#include "wdt.h"
+
+static TimerHandle_t clearer_timer;
+static StaticTimer_t clearer_timer_buffer;
+#define CLEAR_PERIOD pdMS_TO_TICKS(2000)
+
+static void watchdog_clearer_callback()
+{
+	WDT_ResetTimer(MXC_WDT0);
+}
+
+void watchdog_clearer_init()
+{
+	clearer_timer = xTimerCreateStatic(
+		"watchdog_clearer_timer",
+		CLEAR_PERIOD,
+		pdTRUE,
+		NULL,
+		watchdog_clearer_callback,
+		&clearer_timer_buffer
+	);
+	xTimerStart(clearer_timer, 0);
+}
-- 
GitLab