From b1f9cb4406ab811b11fed180eddb98da916bf286 Mon Sep 17 00:00:00 2001
From: schneider <schneider@blinkenlichts.net>
Date: Thu, 18 Jul 2019 01:39:05 +0200
Subject: [PATCH] feat(interrupt): PoC for pyhton interrupts

---
 epicardium/api/common.h      |  2 +-
 epicardium/epicardium.h      |  3 +++
 epicardium/main.c            |  2 ++
 epicardium/meson.build       | 19 ++++++++++++++++++
 epicardium/modules/serial.c  | 10 ++++++++--
 pycardium/meson.build        |  3 ++-
 pycardium/modules/qstrdefs.h |  2 ++
 pycardium/mpconfigport.h     |  3 +++
 pycardium/mphalport.c        | 37 +++++++++++++++++++++++++-----------
 pycardium/mphalport.h        |  3 +++
 10 files changed, 69 insertions(+), 15 deletions(-)

diff --git a/epicardium/api/common.h b/epicardium/api/common.h
index a929f301c..0a94d87ab 100644
--- a/epicardium/api/common.h
+++ b/epicardium/api/common.h
@@ -37,4 +37,4 @@ struct api_call_mem {
 
 /* TODO: Make this address part of the linker script */
 static __attribute__((unused)) struct api_call_mem* API_CALL_MEM =
-	(struct api_call_mem*)0x20080000;
+	(struct api_call_mem*)0x20080100;
diff --git a/epicardium/epicardium.h b/epicardium/epicardium.h
index 7886cc5f0..198b11366 100644
--- a/epicardium/epicardium.h
+++ b/epicardium/epicardium.h
@@ -2,6 +2,9 @@
 #define _EPICARDIUM_H
 #include <stdint.h>
 
+#define INT_CTRL_C  1
+#define INT_BHI     2
+
 #ifndef API
 #define API(id, def) def
 #endif
diff --git a/epicardium/main.c b/epicardium/main.c
index e61f533c2..f7fa71d59 100644
--- a/epicardium/main.c
+++ b/epicardium/main.c
@@ -10,6 +10,7 @@
 #include "leds.h"
 #include "api/dispatcher.h"
 #include "modules/modules.h"
+#include "interrupt/interrupt.h"
 
 #include <Heart.h>
 #include "GUI_Paint.h"
@@ -46,6 +47,7 @@ int main(void)
 
 	cdcacm_init();
 	fatfs_init();
+    interrupt_init();
 
 	printf("=> Initializing tasks ...\n");
 
diff --git a/epicardium/meson.build b/epicardium/meson.build
index 26f36cd47..1deb5842b 100644
--- a/epicardium/meson.build
+++ b/epicardium/meson.build
@@ -39,6 +39,24 @@ api_dispatcher_lib = static_library(
   dependencies: periphdriver,
 )
 
+##########################################################################
+#
+# Interrupts
+#
+##########################################################################
+int_receiver_lib = static_library(
+  'int-receiver',
+  'interrupt/receiver.c',
+  dependencies: periphdriver,
+)
+
+int_receiver = declare_dependency(
+  include_directories: include_directories('.'),
+  link_with: int_receiver_lib,
+  dependencies: periphdriver,
+)
+
+
 ##########################################################################
 #
 # FreeRTOS
@@ -69,6 +87,7 @@ elf = executable(
   'cdcacm.c',
   'main.c',
   'support.c',
+  'interrupt/interrupt.c',
   module_sources,
   dependencies: [libcard10, max32665_startup_core0, maxusb, libff13],
   link_with: [api_dispatcher_lib, freertos],
diff --git a/epicardium/modules/serial.c b/epicardium/modules/serial.c
index 2efc4b921..095e8d89f 100644
--- a/epicardium/modules/serial.c
+++ b/epicardium/modules/serial.c
@@ -4,13 +4,14 @@
 #include "max32665.h"
 #include "cdcacm.h"
 #include "uart.h"
-#include "tmr_utils.h"
 
 #include "FreeRTOS.h"
 #include "task.h"
 #include "queue.h"
 
 #include "modules.h"
+#include "interrupt/interrupt.h"
+
 
 /* Task ID for the serial handler */
 TaskHandle_t serial_task_id = NULL;
@@ -56,9 +57,14 @@ static void enqueue_char(char chr)
 {
 	if (chr == 0x3) {
 		/* Control-C */
-		TMR_TO_Start(MXC_TMR5, 1, 0);
+        interrupt_ctrl_c();
 	}
 
+    if (chr == 0x0e) {
+		/* Control-N */
+        interrupt_bhi();
+    }
+
 	if (xQueueSend(read_queue, &chr, 100) == errQUEUE_FULL) {
 		/* Queue overran, wait a bit */
 		vTaskDelay(portTICK_PERIOD_MS * 50);
diff --git a/pycardium/meson.build b/pycardium/meson.build
index 67698112e..dd7822c7b 100644
--- a/pycardium/meson.build
+++ b/pycardium/meson.build
@@ -4,6 +4,7 @@ modsrc = files(
   'modules/utime.c',
   'modules/leds.c',
   'modules/vibra.c',
+  'modules/interrupt.c',
 )
 
 #################################
@@ -73,7 +74,7 @@ elf = executable(
   modsrc,
   mp_headers,
   include_directories: micropython_includes,
-  dependencies: [max32665_startup_core1, periphdriver, api_caller],
+  dependencies: [max32665_startup_core1, periphdriver, api_caller, int_receiver],
   link_with: upy,
   link_whole: [max32665_startup_core1_lib],
   link_args: [
diff --git a/pycardium/modules/qstrdefs.h b/pycardium/modules/qstrdefs.h
index 2a6dcbe6b..3466d79a5 100644
--- a/pycardium/modules/qstrdefs.h
+++ b/pycardium/modules/qstrdefs.h
@@ -25,3 +25,5 @@ Q(ticks_diff)
 /* vibra */
 Q(vibra)
 Q(vibrate)
+
+Q(set_bhi)
diff --git a/pycardium/mpconfigport.h b/pycardium/mpconfigport.h
index a6aafcb86..d1187611d 100644
--- a/pycardium/mpconfigport.h
+++ b/pycardium/mpconfigport.h
@@ -19,6 +19,8 @@
 #define MICROPY_HELPER_REPL                 (1)
 #define MICROPY_LONGINT_IMPL                (MICROPY_LONGINT_IMPL_LONGLONG)
 
+#define MICROPY_ENABLE_SCHEDULER            (1)
+
 /* Builtin function and modules */
 #define MICROPY_PY_BUILTINS_HELP            (1)
 #define MICROPY_PY_BUILTINS_HELP_MODULES    (1)
@@ -37,6 +39,7 @@
 #define MODULE_UTIME_ENABLED                (1)
 #define MODULE_LEDS_ENABLED                 (1)
 #define MODULE_VIBRA_ENABLED                (1)
+#define MODULE_INTERRUPT_ENABLED            (1)
 
 /*
  * This port is intended to be 32-bit, but unfortunately, int32_t for
diff --git a/pycardium/mphalport.c b/pycardium/mphalport.c
index fdfb592d8..fbdae590c 100644
--- a/pycardium/mphalport.c
+++ b/pycardium/mphalport.c
@@ -14,7 +14,7 @@
 #include "tmr.h"
 
 #include "epicardium.h"
-
+#include "interrupt/int-common.h"
 /******************************************************************************
  * Serial Communication
  */
@@ -64,21 +64,36 @@ long _write(int fd, const char *buf, size_t cnt)
 
 bool do_interrupt = false;
 
+mp_obj_t bhi_callback = NULL;
+
+void mp_hal_interrupt_set_bhi(mp_obj_t func)
+{
+    bhi_callback = func;
+}
+
 /* Timer Interrupt used for control char notification */
 void TMR5_IRQHandler(void)
 {
 	TMR_IntClear(MXC_TMR5);
 
-	if (do_interrupt) {
-		/* Taken from lib/micropython/micropython/lib/utils/interrupt_char.c */
-		MP_STATE_VM(mp_pending_exception) =
-			MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_kbd_exception));
-#if MICROPY_ENABLE_SCHEDULER
-		if (MP_STATE_VM(sched_state) == MP_SCHED_IDLE) {
-			MP_STATE_VM(sched_state) = MP_SCHED_PENDING;
-		}
-#endif
-	}
+    switch(INT_CALL_MEM->id) {
+    case INT_CTRL_C:
+        if (do_interrupt) {
+            /* Taken from lib/micropython/micropython/lib/utils/interrupt_char.c */
+            MP_STATE_VM(mp_pending_exception) =
+                MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_kbd_exception));
+    #if MICROPY_ENABLE_SCHEDULER
+            if (MP_STATE_VM(sched_state) == MP_SCHED_IDLE) {
+                MP_STATE_VM(sched_state) = MP_SCHED_PENDING;
+            }
+    #endif
+        }
+    break;
+    case INT_BHI:
+        mp_sched_schedule(bhi_callback, 0);
+    break;
+    }
+    INT_CALL_MEM->id = 0;
 }
 
 void mp_hal_set_interrupt_char(char c)
diff --git a/pycardium/mphalport.h b/pycardium/mphalport.h
index 79e25cde7..df1e84caa 100644
--- a/pycardium/mphalport.h
+++ b/pycardium/mphalport.h
@@ -1,4 +1,5 @@
 #include "py/mpconfig.h"
+#include "py/obj.h"
 
 /* TODO: Replace this with a proper implementation */
 static inline mp_uint_t mp_hal_ticks_ms(void)
@@ -7,3 +8,5 @@ static inline mp_uint_t mp_hal_ticks_ms(void)
 }
 
 void mp_hal_set_interrupt_char(char c);
+
+void mp_hal_interrupt_set_bhi(mp_obj_t func);
-- 
GitLab