From be09c12759d7aa76b7b42d65dacb044b85759dfc Mon Sep 17 00:00:00 2001
From: Rahix <rahix@rahix.de>
Date: Tue, 13 Aug 2019 11:04:02 +0200
Subject: [PATCH] feat(epicardium): Add module for hardware init

Signed-off-by: Rahix <rahix@rahix.de>
---
 epicardium/main.c              |  5 ++++-
 epicardium/modules/hardware.c  | 40 ++++++++++++++++++++++++++++++++++
 epicardium/modules/meson.build |  1 +
 epicardium/modules/modules.h   |  6 +++++
 4 files changed, 51 insertions(+), 1 deletion(-)
 create mode 100644 epicardium/modules/hardware.c

diff --git a/epicardium/main.c b/epicardium/main.c
index cd989f4c..1ae2dde0 100644
--- a/epicardium/main.c
+++ b/epicardium/main.c
@@ -36,7 +36,8 @@ int main(void)
 	LOG_INFO("startup", "Epicardium startup ...");
 	LOG_INFO("startup", "Version " CARD10_VERSION);
 
-	card10_init();
+	hardware_early_init();
+
 #ifdef CARD10_DEBUG_CORE1
 	LOG_WARN("startup", "Core 1 Debugger Mode");
 	static const gpio_cfg_t swclk = {
@@ -157,6 +158,8 @@ int main(void)
 		core1_load((void *)0x10080000, "main.py");
 	}
 
+	hardware_init();
+
 	LOG_INFO("startup", "Starting FreeRTOS ...");
 	vTaskStartScheduler();
 
diff --git a/epicardium/modules/hardware.c b/epicardium/modules/hardware.c
new file mode 100644
index 00000000..ee369248
--- /dev/null
+++ b/epicardium/modules/hardware.c
@@ -0,0 +1,40 @@
+#include "modules/modules.h"
+
+#include "card10.h"
+
+/*
+ * Early init is called at the very beginning and is meant for modules which
+ * absolutely need to start as soon as possible.  hardware_early_init() blocks
+ * which means code in here should be fast.
+ */
+int hardware_early_init(void)
+{
+	card10_init();
+	return 0;
+}
+
+/*
+ * hardware_init() is called after the core has been bootstrapped and is meant
+ * for less critical initialization steps.  Modules which initialize here should
+ * be robust against a l0dable using their API before initialization is done.
+ *
+ * Ideally, acquire a lock in hardware_early_init() and release it in
+ * hardware_init() once initialization is done.
+ */
+int hardware_init(void)
+{
+	return 0;
+}
+
+/*
+ * hardware_reset() is called whenever a new l0dable is started.  hardware_reset()
+ * should bring all peripherals back into a known initial state.  This does not
+ * necessarily mean resetting the peripheral entirely but hardware_reset()
+ * should at least bring the API facing part of a peripheral back into the state
+ * a fresh booted l0dable expects.
+ */
+int hardware_reset(void)
+{
+	card10_init();
+	return 0;
+}
diff --git a/epicardium/modules/meson.build b/epicardium/modules/meson.build
index 9a70957d..ba1a4fd4 100644
--- a/epicardium/modules/meson.build
+++ b/epicardium/modules/meson.build
@@ -2,6 +2,7 @@ module_sources = files(
   'dispatcher.c',
   'display.c',
   'fileops.c',
+  'hardware.c',
   'leds.c',
   'light_sensor.c',
   'log.c',
diff --git a/epicardium/modules/modules.h b/epicardium/modules/modules.h
index ea2a313f..df1a9d9b 100644
--- a/epicardium/modules/modules.h
+++ b/epicardium/modules/modules.h
@@ -11,6 +11,11 @@ void vApiDispatcher(void *pvParameters);
 extern SemaphoreHandle_t api_mutex;
 extern TaskHandle_t dispatcher_task_id;
 
+/* ---------- Hardware Init & Reset ---------------------------------------- */
+int hardware_early_init(void);
+int hardware_init(void);
+int hardware_reset(void);
+
 /* ---------- Serial ------------------------------------------------------- */
 #define SERIAL_READ_BUFFER_SIZE 128
 void vSerialTask(void *pvParameters);
@@ -27,4 +32,5 @@ void ble_uart_write(uint8_t *pValue, uint8_t len);
 
 // Forces an unlock of the display. Only to be used in epicardium
 void disp_forcelock();
+
 #endif /* MODULES_H */
-- 
GitLab