Skip to content
Snippets Groups Projects
Verified Commit 7fefa791 authored by rahix's avatar rahix
Browse files

feat: Port everything to auto-generated IRQ system


Signed-off-by: default avatarRahix <rahix@rahix.de>
parent cce8a4cf
No related branches found
No related tags found
No related merge requests found
...@@ -3,33 +3,12 @@ ...@@ -3,33 +3,12 @@
#include "api/common.h" #include "api/common.h"
#include "epicardium.h" #include "epicardium.h"
void api_interrupt_handler_ctrl_c(api_int_id_t id) void __dispatch_isr(api_int_id_t);
__attribute__((weak, alias("api_interrupt_handler_default")));
void api_interrupt_handler_bhi160(api_int_id_t id)
__attribute__((weak, alias("api_interrupt_handler_default")));
/* Timer Interrupt used for control char notification */ /* Timer Interrupt used for control char notification */
void TMR5_IRQHandler(void) void TMR5_IRQHandler(void)
{ {
TMR_IntClear(MXC_TMR5); TMR_IntClear(MXC_TMR5);
__dispatch_isr(API_CALL_MEM->int_id);
switch (API_CALL_MEM->int_id) {
case API_INT_CTRL_C:
api_interrupt_handler_ctrl_c(API_CALL_MEM->int_id);
break;
case API_INT_BHI160:
api_interrupt_handler_bhi160(API_CALL_MEM->int_id);
break;
}
API_CALL_MEM->int_id = 0; API_CALL_MEM->int_id = 0;
} }
__attribute__((weak)) void api_interrupt_handler_catch_all(api_int_id_t id)
{
}
void api_interrupt_handler_default(api_int_id_t id)
{
api_interrupt_handler_catch_all(id);
}
...@@ -2,15 +2,15 @@ ...@@ -2,15 +2,15 @@
#include "api/common.h" #include "api/common.h"
#include "tmr_utils.h" #include "tmr_utils.h"
static bool enabled[API_INT_MAX + 1]; static bool int_enabled[EPIC_INT_NUM];
int api_interrupt_trigger(api_int_id_t id) int api_interrupt_trigger(api_int_id_t id)
{ {
if (id > API_INT_MAX) { if (id >= EPIC_INT_NUM) {
return -EINVAL; return -EINVAL;
} }
if (enabled[id]) { if (int_enabled[id]) {
while (API_CALL_MEM->int_id) while (API_CALL_MEM->int_id)
; ;
API_CALL_MEM->int_id = id; API_CALL_MEM->int_id = id;
...@@ -21,30 +21,29 @@ int api_interrupt_trigger(api_int_id_t id) ...@@ -21,30 +21,29 @@ int api_interrupt_trigger(api_int_id_t id)
void api_interrupt_init(void) void api_interrupt_init(void)
{ {
int i;
API_CALL_MEM->int_id = 0; API_CALL_MEM->int_id = 0;
for (i = 0; i <= API_INT_MAX; i++) { for (int i = 0; i < EPIC_INT_NUM; i++) {
enabled[i] = false; int_enabled[i] = false;
} }
} }
int epic_interrupt_enable(api_int_id_t int_id) int epic_interrupt_enable(api_int_id_t int_id)
{ {
if (int_id > API_INT_MAX) { if (int_id >= EPIC_INT_NUM) {
return -EINVAL; return -EINVAL;
} }
enabled[int_id] = true; int_enabled[int_id] = true;
return 0; return 0;
} }
int epic_interrupt_disable(api_int_id_t int_id) int epic_interrupt_disable(api_int_id_t int_id)
{ {
if (int_id > API_INT_MAX) { if (int_id >= EPIC_INT_NUM) {
return -EINVAL; return -EINVAL;
} }
enabled[int_id] = false; int_enabled[int_id] = false;
return 0; return 0;
} }
#pragma once #pragma once
#include "api/common.h" #include "api/common.h"
void api_interrupt_init(void); void api_interrupt_init(void);
int api_interrupt_trigger(api_int_id_t id); int api_interrupt_trigger(api_int_id_t id);
...@@ -11,18 +11,22 @@ ...@@ -11,18 +11,22 @@
typedef unsigned int size_t; typedef unsigned int size_t;
#endif /* __SPHINX_DOC */ #endif /* __SPHINX_DOC */
/* clang-format off */
#define API_INT_CTRL_C 1
#define API_INT_BHI160 2
#define API_INT_MAX API_INT_BHI160
/* /*
* These definitions are required for the code-generator. Please don't touch! * These definitions are required for the code-generator. Please don't touch!
*/ */
#ifndef API #ifndef API
#define API(id, def) def #define API(id, def) def
#endif #endif
#ifndef API_ISR
#define API_ISR(id, isr) void isr(void);
#endif
/*
* IDs for all defined API calls. These IDs should not be needed in application
* code on any side.
*/
/* clang-format off */
#define API_UART_WRITE 0x1 #define API_UART_WRITE 0x1
#define API_UART_READ 0x2 #define API_UART_READ 0x2
#define API_LEDS_SET 0x3 #define API_LEDS_SET 0x3
...@@ -31,9 +35,53 @@ typedef unsigned int size_t; ...@@ -31,9 +35,53 @@ typedef unsigned int size_t;
#define API_STREAM_READ 0x6 #define API_STREAM_READ 0x6
#define API_INTERRUPT_ENABLE 0x7 #define API_INTERRUPT_ENABLE 0x7
#define API_INTERRUPT_DISABLE 0x8 #define API_INTERRUPT_DISABLE 0x8
/* clang-format on */
typedef uint32_t api_int_id_t;
/**
* Interrupts
* ==========
* Next to API calls, Epicardium API also has an interrupt mechanism to serve
* the other direction. These interrupts can be enabled/disabled
* (masked/unmasked) using :c:func:`epic_interrupt_enable` and
* :c:func:`epic_interrupt_disable`.
*/
/**
* Enable/unmask an API interrupt.
*
* :param int_id: The interrupt to be enabled
*/
API(API_INTERRUPT_ENABLE, int epic_interrupt_enable(api_int_id_t int_id));
/**
* Disable/mask an API interrupt.
*
* :param int_id: The interrupt to be disabled
*/
API(API_INTERRUPT_DISABLE, int epic_interrupt_disable(api_int_id_t int_id));
/**
* The following interrupts are defined:
*/
/* clang-format off */
/** Reset Handler? **TODO** */
#define EPIC_INT_RESET 0
/** ``^C`` interrupt. See :c:func:`epic_isr_ctrl_c` for details. */
#define EPIC_INT_CTRL_C 1
/* Debug interrupt, please ignore */
#define EPIC_INT_BHI160_TEST 2
API_ISR(EPIC_INT_BHI160_TEST, epic_isr_bhi160_test);
/* Number of defined interrupts. */
#define EPIC_INT_NUM 3
/* clang-format on */ /* clang-format on */
API_ISR(EPIC_INT_RESET, epic_isr_reset);
/** /**
* UART/Serial Interface * UART/Serial Interface
* ===================== * =====================
...@@ -60,6 +108,21 @@ API(API_UART_WRITE, void epic_uart_write_str(const char *str, intptr_t length)); ...@@ -60,6 +108,21 @@ API(API_UART_WRITE, void epic_uart_write_str(const char *str, intptr_t length));
*/ */
API(API_UART_READ, char epic_uart_read_chr(void)); API(API_UART_READ, char epic_uart_read_chr(void));
/**
* **Interrupt Service Routine**
*
* A user-defineable ISR which is triggered when a ``^C`` (``0x04``) is received
* on any serial input device. This function is weakly aliased to
* :c:func:`epic_isr_default` by default.
*
* To enable this interrupt, you need to enable :c:data:`EPIC_INT_CTRL_C`:
*
* .. code-block:: cpp
*
* epic_interrupt_enable(EPIC_INT_CTRL_C);
*/
API_ISR(EPIC_INT_CTRL_C, epic_isr_ctrl_c);
/** /**
* LEDs * LEDs
* ==== * ====
...@@ -156,23 +219,4 @@ API(API_VIBRA_SET, void epic_vibra_set(int status)); ...@@ -156,23 +219,4 @@ API(API_VIBRA_SET, void epic_vibra_set(int status));
*/ */
API(API_VIBRA_VIBRATE, void epic_vibra_vibrate(int millis)); API(API_VIBRA_VIBRATE, void epic_vibra_vibrate(int millis));
/**
* API interrupt type
*/
typedef uint32_t api_int_id_t;
/**
* Enable/unmask an API interrupt
*
* :param int_id: The interrupt to be enabled
*/
API(API_INTERRUPT_ENABLE, int epic_interrupt_enable(api_int_id_t int_id));
/**
* Disable/mask an API interrupt
*
* :param int_id: The interrupt to be disabled
*/
API(API_INTERRUPT_DISABLE, int epic_interrupt_disable(api_int_id_t int_id));
#endif /* _EPICARDIUM_H */ #endif /* _EPICARDIUM_H */
...@@ -57,12 +57,12 @@ static void enqueue_char(char chr) ...@@ -57,12 +57,12 @@ static void enqueue_char(char chr)
{ {
if (chr == 0x3) { if (chr == 0x3) {
/* Control-C */ /* Control-C */
api_interrupt_trigger(API_INT_CTRL_C); api_interrupt_trigger(EPIC_INT_CTRL_C);
} }
if (chr == 0x0e) { if (chr == 0x0e) {
/* Control-N */ /* Control-N */
api_interrupt_trigger(API_INT_BHI160); api_interrupt_trigger(EPIC_INT_BHI160_TEST);
} }
if (xQueueSend(read_queue, &chr, 100) == errQUEUE_FULL) { if (xQueueSend(read_queue, &chr, 100) == errQUEUE_FULL) {
......
...@@ -6,15 +6,15 @@ ...@@ -6,15 +6,15 @@
#include "mphalport.h" #include "mphalport.h"
// TODO: these should be intialized as mp_const_none // TODO: these should be intialized as mp_const_none
mp_obj_t callbacks[API_INT_MAX + 1] = { mp_obj_t callbacks[EPIC_INT_NUM] = {
0, 0,
}; };
void api_interrupt_handler_catch_all(api_int_id_t id) void epic_isr_default_handler(api_int_id_t id)
{ {
// TODO: check if id is out of rante // TODO: check if id is out of rante
// TOOD: check against mp_const_none // TOOD: check against mp_const_none
if (id <= API_INT_MAX) { if (id < EPIC_INT_NUM) {
if (callbacks[id]) { if (callbacks[id]) {
mp_sched_schedule( mp_sched_schedule(
callbacks[id], MP_OBJ_NEW_SMALL_INT(id) callbacks[id], MP_OBJ_NEW_SMALL_INT(id)
...@@ -32,7 +32,7 @@ STATIC mp_obj_t mp_interrupt_set_callback(mp_obj_t id_in, mp_obj_t callback_obj) ...@@ -32,7 +32,7 @@ STATIC mp_obj_t mp_interrupt_set_callback(mp_obj_t id_in, mp_obj_t callback_obj)
} }
// TODO: throw error if id is out of range // TODO: throw error if id is out of range
if (id <= API_INT_MAX) { if (id < EPIC_INT_NUM) {
callbacks[id] = callback_obj; callbacks[id] = callback_obj;
} }
......
...@@ -62,7 +62,7 @@ long _write(int fd, const char *buf, size_t cnt) ...@@ -62,7 +62,7 @@ long _write(int fd, const char *buf, size_t cnt)
return cnt; return cnt;
} }
void api_interrupt_handler_ctrl_c(void) void epic_isr_ctrl_c(void)
{ {
/* Taken from lib/micropython/micropython/lib/utils/interrupt_char.c */ /* Taken from lib/micropython/micropython/lib/utils/interrupt_char.c */
MP_STATE_VM(mp_pending_exception) = MP_STATE_VM(mp_pending_exception) =
...@@ -83,9 +83,9 @@ void mp_hal_set_interrupt_char(char c) ...@@ -83,9 +83,9 @@ void mp_hal_set_interrupt_char(char c)
} }
if (c == 0x03) { if (c == 0x03) {
epic_interrupt_enable(API_INT_CTRL_C); epic_interrupt_enable(EPIC_INT_CTRL_C);
} else { } else {
epic_interrupt_disable(API_INT_CTRL_C); epic_interrupt_disable(EPIC_INT_CTRL_C);
} }
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment