Skip to content
Snippets Groups Projects
Commit 52b1fbbc authored by rahix's avatar rahix
Browse files

chore(interrupts): Move api into an epicardium module


Signed-off-by: default avatarRahix <rahix@rahix.de>
parent 079982a6
No related branches found
No related tags found
1 merge request!377Dispatch interrupts asynchroneously
......@@ -3,49 +3,20 @@
#include "tmr_utils.h"
#include <assert.h>
static bool int_enabled[EPIC_INT_NUM];
void api_interrupt_trigger(api_int_id_t id)
{
assert(id < EPIC_INT_NUM);
if (int_enabled[id]) {
while (API_CALL_MEM->int_id != (api_int_id_t)(-1))
;
API_CALL_MEM->int_id = id;
TMR_TO_Start(MXC_TMR5, 1, 0);
}
}
void api_interrupt_init(void)
{
API_CALL_MEM->int_id = (-1);
for (int i = 0; i < EPIC_INT_NUM; i++) {
int_enabled[i] = false;
}
/* Reset interrupt is always enabled */
int_enabled[EPIC_INT_RESET] = true;
}
int epic_interrupt_enable(api_int_id_t int_id)
bool api_interrupt_is_ready(void)
{
if (int_id >= EPIC_INT_NUM) {
return -EINVAL;
}
int_enabled[int_id] = true;
return 0;
return API_CALL_MEM->int_id == (api_int_id_t)(-1);
}
int epic_interrupt_disable(api_int_id_t int_id)
void api_interrupt_trigger(api_int_id_t id)
{
if (int_id >= EPIC_INT_NUM || int_id == EPIC_INT_RESET) {
return -EINVAL;
}
assert(API_CALL_MEM->int_id == (api_int_id_t)(-1));
int_enabled[int_id] = false;
return 0;
API_CALL_MEM->int_id = id;
TMR_TO_Start(MXC_TMR5, 1, 0);
}
......@@ -2,4 +2,5 @@
#include "api/common.h"
void api_interrupt_init(void);
bool api_interrupt_is_ready(void);
void api_interrupt_trigger(api_int_id_t id);
#include "epicardium.h"
#include "api/dispatcher.h"
#include "api/interrupt-sender.h"
#include "usb/epc_usb.h"
#include "modules/filesystem.h"
#include "modules/log.h"
......@@ -171,7 +170,7 @@ int hardware_early_init(void)
/*
* API Dispatcher & API Interrupts
*/
api_interrupt_init();
interrupt_init();
api_dispatcher_init();
/*
......@@ -237,7 +236,7 @@ int hardware_reset(void)
/*
* API Dispatcher & API Interrupts
*/
api_interrupt_init();
interrupt_init();
api_dispatcher_init();
/*
......
#include "modules/mutex.h"
#include "epicardium.h"
#include "api/interrupt-sender.h"
#include <assert.h>
struct interrupt_priv {
/* Whether this interrupt can be triggered */
bool int_enabled[EPIC_INT_NUM];
/* Whether this interrupt is waiting to be delivered */
bool int_pending[EPIC_INT_NUM];
/* Whether any interrupts are currently waiting to be triggered */
bool has_pending;
};
static struct interrupt_priv interrupt_data;
static struct mutex interrupt_mutex;
void interrupt_trigger(api_int_id_t id)
{
assert(id < EPIC_INT_NUM);
mutex_lock(&interrupt_mutex);
if (!interrupt_data.int_enabled[id])
goto out;
while (!api_interrupt_is_ready())
;
api_interrupt_trigger(id);
out:
mutex_unlock(&interrupt_mutex);
}
/*
* This function solely exists because of that one use of interrupts that breaks
* the rules: The RTC ALARM interrupt is triggered from a hardware ISR where
* interrupt_trigger_sync() won't work because it needs to lock a mutex.
*
* DO NOT USE THIS FUNCTION IN ANY NEW CODE.
*/
void __attribute__((deprecated)) interrupt_trigger_unsafe(api_int_id_t id)
{
assert(id < EPIC_INT_NUM);
if (!interrupt_data.int_enabled[id])
return;
while (!api_interrupt_is_ready())
;
api_interrupt_trigger(id);
}
static void interrupt_set_enabled(api_int_id_t id, bool enabled)
{
assert(id < EPIC_INT_NUM);
mutex_lock(&interrupt_mutex);
interrupt_data.int_enabled[id] = enabled;
mutex_unlock(&interrupt_mutex);
}
void interrupt_init(void)
{
if (interrupt_mutex.name == NULL)
mutex_create(&interrupt_mutex);
api_interrupt_init();
/* Reset all irqs to disabled */
for (size_t i = 0; i < EPIC_INT_NUM; i++) {
interrupt_set_enabled(i, false);
}
/* Reset interrupt is always enabled */
interrupt_set_enabled(EPIC_INT_RESET, true);
}
/* Epic-calls {{{ */
int epic_interrupt_enable(api_int_id_t int_id)
{
if (int_id >= EPIC_INT_NUM) {
return -EINVAL;
}
interrupt_set_enabled(int_id, true);
return 0;
}
int epic_interrupt_disable(api_int_id_t int_id)
{
if (int_id >= EPIC_INT_NUM || int_id == EPIC_INT_RESET) {
return -EINVAL;
}
interrupt_set_enabled(int_id, false);
return 0;
}
/* }}} */
......@@ -9,6 +9,7 @@ module_sources = files(
'gpio.c',
'hardware.c',
'hw-lock.c',
'interrupts.c',
'leds.c',
'lifecycle.c',
'light_sensor.c',
......
......@@ -4,6 +4,7 @@
#include "FreeRTOS.h"
#include "gpio.h"
#include "modules/mutex.h"
#include "epicardium.h"
#include <stdint.h>
#include <stdbool.h>
......@@ -27,6 +28,13 @@ int hardware_reset(void);
void vLifecycleTask(void *pvParameters);
void return_to_menu(void);
/* ---------- Interrupts --------------------------------------------------- */
void interrupt_init(void);
void interrupt_trigger(api_int_id_t id);
void interrupt_trigger_unsafe(api_int_id_t id) __attribute__((deprecated(
"interrupt_trigger_unsafe() is racy and only exists for legacy code."
)));
/* ---------- Serial ------------------------------------------------------- */
#define SERIAL_READ_BUFFER_SIZE 128
#define SERIAL_WRITE_STREAM_BUFFER_SIZE 512
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment