Verified Commit 7fefa791 authored by Rahix's avatar Rahix
Browse files

feat: Port everything to auto-generated IRQ system



Signed-off-by: Rahix's avatarRahix <rahix@rahix.de>
parent cce8a4cf
......@@ -3,33 +3,12 @@
#include "api/common.h"
#include "epicardium.h"
void api_interrupt_handler_ctrl_c(api_int_id_t id)
__attribute__((weak, alias("api_interrupt_handler_default")));
void api_interrupt_handler_bhi160(api_int_id_t id)
__attribute__((weak, alias("api_interrupt_handler_default")));
void __dispatch_isr(api_int_id_t);
/* Timer Interrupt used for control char notification */
void TMR5_IRQHandler(void)
{
TMR_IntClear(MXC_TMR5);
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;
}
__dispatch_isr(API_CALL_MEM->int_id);
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 @@
#include "api/common.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)
{
if (id > API_INT_MAX) {
if (id >= EPIC_INT_NUM) {
return -EINVAL;
}
if (enabled[id]) {
if (int_enabled[id]) {
while (API_CALL_MEM->int_id)
;
API_CALL_MEM->int_id = id;
......@@ -21,30 +21,29 @@ int api_interrupt_trigger(api_int_id_t id)
void api_interrupt_init(void)
{
int i;
API_CALL_MEM->int_id = 0;
for (i = 0; i <= API_INT_MAX; i++) {
enabled[i] = false;
for (int i = 0; i < EPIC_INT_NUM; i++) {
int_enabled[i] = false;
}
}
int epic_interrupt_enable(api_int_id_t int_id)
{
if (int_id > API_INT_MAX) {
if (int_id >= EPIC_INT_NUM) {
return -EINVAL;
}
enabled[int_id] = true;
int_enabled[int_id] = true;
return 0;
}
int epic_interrupt_disable(api_int_id_t int_id)
{
if (int_id > API_INT_MAX) {
if (int_id >= EPIC_INT_NUM) {
return -EINVAL;
}
enabled[int_id] = false;
int_enabled[int_id] = false;
return 0;
}
#pragma once
#include "api/common.h"
void api_interrupt_init(void);
int api_interrupt_trigger(api_int_id_t id);
......@@ -11,18 +11,22 @@
typedef unsigned int size_t;
#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!
*/
#ifndef API
#define API(id, def) def
#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_READ 0x2
#define API_LEDS_SET 0x3
......@@ -31,9 +35,53 @@ typedef unsigned int size_t;
#define API_STREAM_READ 0x6
#define API_INTERRUPT_ENABLE 0x7
#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 */
API_ISR(EPIC_INT_RESET, epic_isr_reset);
/**
* UART/Serial Interface
* =====================
......@@ -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));
/**
* **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
* ====
......@@ -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 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 */
......@@ -57,12 +57,12 @@ static void enqueue_char(char chr)
{
if (chr == 0x3) {
/* Control-C */
api_interrupt_trigger(API_INT_CTRL_C);
api_interrupt_trigger(EPIC_INT_CTRL_C);
}
if (chr == 0x0e) {
/* Control-N */
api_interrupt_trigger(API_INT_BHI160);
api_interrupt_trigger(EPIC_INT_BHI160_TEST);
}
if (xQueueSend(read_queue, &chr, 100) == errQUEUE_FULL) {
......
......@@ -6,15 +6,15 @@
#include "mphalport.h"
// 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,
};
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
// TOOD: check against mp_const_none
if (id <= API_INT_MAX) {
if (id < EPIC_INT_NUM) {
if (callbacks[id]) {
mp_sched_schedule(
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)
}
// TODO: throw error if id is out of range
if (id <= API_INT_MAX) {
if (id < EPIC_INT_NUM) {
callbacks[id] = callback_obj;
}
......
......@@ -62,7 +62,7 @@ long _write(int fd, const char *buf, size_t 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 */
MP_STATE_VM(mp_pending_exception) =
......@@ -83,9 +83,9 @@ void mp_hal_set_interrupt_char(char c)
}
if (c == 0x03) {
epic_interrupt_enable(API_INT_CTRL_C);
epic_interrupt_enable(EPIC_INT_CTRL_C);
} else {
epic_interrupt_disable(API_INT_CTRL_C);
epic_interrupt_disable(EPIC_INT_CTRL_C);
}
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment