Ver código fonte

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
DrZlo13 5 anos atrás
pai
commit
3ba1738acd

+ 5 - 5
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);
 

+ 65 - 0
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);
+        }
+    }
+}

+ 19 - 0
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);

+ 4 - 0
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;
 }

+ 1 - 0
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"

+ 6 - 0
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);
+}