From 3ba1738acd9ae1d474c9cb3c7d37672122f4e8aa Mon Sep 17 00:00:00 2001 From: DrZlo13 Date: Sat, 19 Dec 2020 05:26:03 +1000 Subject: [PATCH] FL-262 Interrupt manager (#270) * interrupt manager * init interrupt manager * add usage to lf-rfid app * check ready flag * move interrupts code to target hal * fix path --- applications/lf-rfid/lf-rfid.c | 10 +-- core/api-hal/api-interrupt-mgr.c | 65 ++++++++++++++++++++ core/api-hal/api-interrupt-mgr.h | 19 ++++++ core/flipper_v2.c | 4 ++ core/flipper_v2.h | 1 + firmware/targets/f4/api-hal/api-interrupts.c | 6 ++ 6 files changed, 100 insertions(+), 5 deletions(-) create mode 100644 core/api-hal/api-interrupt-mgr.c create mode 100644 core/api-hal/api-interrupt-mgr.h create mode 100644 firmware/targets/f4/api-hal/api-interrupts.c diff --git a/applications/lf-rfid/lf-rfid.c b/applications/lf-rfid/lf-rfid.c index d75ccfff..4c2c25c0 100644 --- a/applications/lf-rfid/lf-rfid.c +++ b/applications/lf-rfid/lf-rfid.c @@ -62,10 +62,8 @@ GpioPin debug_1 = {.pin = GPIO_PIN_3, .port = GPIOC}; extern COMP_HandleTypeDef hcomp1; -void* comp_ctx = NULL; - -void HAL_COMP_TriggerCallback(COMP_HandleTypeDef* hcomp) { - if(hcomp != &hcomp1) return; +void comparator_trigger_callback(void* hcomp, void* comp_ctx) { + if((COMP_HandleTypeDef*)hcomp != &hcomp1) return; // gpio_write(&debug_0, true); @@ -178,7 +176,9 @@ void lf_rfid_workaround(void* p) { gpio_write((GpioPin*)&ibutton_gpio, false); // init ctx - comp_ctx = (void*)event_queue; + void* comp_ctx = (void*)event_queue; + api_interrupt_add(comparator_trigger_callback, InterruptTypeComparatorTrigger, comp_ctx); + // start comp HAL_COMP_Start(&hcomp1); diff --git a/core/api-hal/api-interrupt-mgr.c b/core/api-hal/api-interrupt-mgr.c new file mode 100644 index 00000000..3fa27481 --- /dev/null +++ b/core/api-hal/api-interrupt-mgr.c @@ -0,0 +1,65 @@ +#include "api-interrupt-mgr.h" + +LIST_DEF(list_interrupt, InterruptCallbackItem, M_POD_OPLIST); +list_interrupt_t interrupts; +osMutexId_t interrupt_list_mutex; + +bool api_interrupt_init() { + interrupt_list_mutex = osMutexNew(NULL); + return (interrupt_list_mutex != NULL); +} + +void api_interrupt_add(InterruptCallback callback, InterruptType type, void* context) { + if(osMutexAcquire(interrupt_list_mutex, osWaitForever) == osOK) { + // put uninitialized item to the list + // M_POD_OPLIST provide memset(&(a), 0, sizeof (a)) constructor + // so item will not be ready until we set ready flag + InterruptCallbackItem* item = list_interrupt_push_new(interrupts); + + // initialize item + item->callback = callback; + item->type = type; + item->context = context; + item->ready = true; + + // TODO remove on app exit + //flapp_on_exit(api_interrupt_remove, callback); + + osMutexRelease(interrupt_list_mutex); + } +} + +void api_interrupt_remove(InterruptCallback callback) { + if(osMutexAcquire(interrupt_list_mutex, osWaitForever) == osOK) { + // iterate over items + list_interrupt_it_t it; + for(list_interrupt_it(it, interrupts); !list_interrupt_end_p(it); + list_interrupt_next(it)) { + const InterruptCallbackItem* item = list_interrupt_cref(it); + + // if the iterator is equal to our element + if(item->callback == callback) { + list_interrupt_remove(interrupts, it); + break; + } + } + + osMutexRelease(interrupt_list_mutex); + } +} + +void api_interrupt_call(InterruptType type, void* hw) { + // that executed in interrupt ctx so mutex don't needed + // but we need to check ready flag + + // iterate over items + list_interrupt_it_t it; + for(list_interrupt_it(it, interrupts); !list_interrupt_end_p(it); list_interrupt_next(it)) { + const InterruptCallbackItem* item = list_interrupt_cref(it); + + // if the iterator is equal to our element + if(item->type == type && item->ready) { + item->callback(hw, item->context); + } + } +} \ No newline at end of file diff --git a/core/api-hal/api-interrupt-mgr.h b/core/api-hal/api-interrupt-mgr.h new file mode 100644 index 00000000..b6ffe5b4 --- /dev/null +++ b/core/api-hal/api-interrupt-mgr.h @@ -0,0 +1,19 @@ +#pragma once +#include "flipper_v2.h" + +typedef void (*InterruptCallback)(void*, void*); + +typedef enum { + InterruptTypeComparatorTrigger = 0, +} InterruptType; + +typedef struct { + InterruptCallback callback; + InterruptType type; + void* context; + bool ready; +} InterruptCallbackItem; + +bool api_interrupt_init(); +void api_interrupt_add(InterruptCallback callback, InterruptType type, void* context); +void api_interrupt_remove(InterruptCallback callback); \ No newline at end of file diff --git a/core/flipper_v2.c b/core/flipper_v2.c index 87ea47ce..d84dfda5 100644 --- a/core/flipper_v2.c +++ b/core/flipper_v2.c @@ -11,5 +11,9 @@ bool init_flipper_api(void) { no_errors = false; } + if(!api_interrupt_init()) { + no_errors = false; + } + return no_errors; } \ No newline at end of file diff --git a/core/flipper_v2.h b/core/flipper_v2.h index f2e344be..012d2aab 100644 --- a/core/flipper_v2.h +++ b/core/flipper_v2.h @@ -18,6 +18,7 @@ extern "C" { #include "api-basic/check.h" #include "api-hal/api-gpio.h" +#include "api-hal/api-interrupt-mgr.h" #include "api-hal-resources.h" #include "gui/gui.h" diff --git a/firmware/targets/f4/api-hal/api-interrupts.c b/firmware/targets/f4/api-hal/api-interrupts.c new file mode 100644 index 00000000..59e362a6 --- /dev/null +++ b/firmware/targets/f4/api-hal/api-interrupts.c @@ -0,0 +1,6 @@ +#include "api-hal/api-interrupt-mgr.h" + +/* interrupts */ +void HAL_COMP_TriggerCallback(COMP_HandleTypeDef* hcomp) { + api_interrupt_call(InterruptTypeComparatorTrigger, hcomp); +} \ No newline at end of file