diff --git a/core/api-hal/api-interrupt-mgr.c b/core/api-hal/api-interrupt-mgr.c index f412fba1f..20375bf15 100644 --- a/core/api-hal/api-interrupt-mgr.c +++ b/core/api-hal/api-interrupt-mgr.c @@ -1,123 +1,65 @@ #include "api-interrupt-mgr.h" -#include "mlib/m-dict.h" - -#include #include +#include -LIST_DEF(list_interrupt, InterruptCallbackItem, M_POD_OPLIST); -DICT_DEF2(dict_interrupt, uint32_t, M_DEFAULT_OPLIST, list_interrupt_t, M_A1_OPLIST); - -dict_interrupt_t interrupts_dict; -osMutexId_t interrupt_mutex; +static volatile InterruptCallbackItem callback_list[InterruptTypeLast]; bool api_interrupt_init() { - dict_interrupt_init(interrupts_dict); - interrupt_mutex = osMutexNew(NULL); - return (interrupt_mutex != NULL); + for(uint8_t i = 0; i < InterruptTypeLast; i++) { + callback_list[i].callback = NULL; + callback_list[i].context = NULL; + callback_list[i].ready = false; + } + + return true; } void api_interrupt_add(InterruptCallback callback, InterruptType type, void* context) { - if(osMutexAcquire(interrupt_mutex, osWaitForever) == osOK) { - list_interrupt_t* list = dict_interrupt_get(interrupts_dict, (uint32_t)type); + furi_assert(type < InterruptTypeLast); + furi_check(callback_list[type].callback == NULL); - if(list == NULL) { - list_interrupt_t new_list; - list_interrupt_init(new_list); - dict_interrupt_set_at(interrupts_dict, (uint32_t)type, new_list); - list = dict_interrupt_get(interrupts_dict, (uint32_t)type); - } - - // 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(*list); - - // initialize item - item->callback = callback; - item->type = type; - item->context = context; - asm volatile("dmb" : : : "memory"); - item->ready = true; - - osMutexRelease(interrupt_mutex); - } + callback_list[type].callback = callback; + callback_list[type].context = context; + __DMB(); + callback_list[type].ready = true; } void api_interrupt_remove(InterruptCallback callback, InterruptType type) { - if(osMutexAcquire(interrupt_mutex, osWaitForever) == osOK) { - list_interrupt_t* list = dict_interrupt_get(interrupts_dict, (uint32_t)type); - - if(list != NULL) { - // iterate over items - list_interrupt_it_t it; - list_interrupt_it(it, *list); - while(!list_interrupt_end_p(it)) { - if(it->current->data.callback == callback) { - list_interrupt_remove(*list, it); - } else { - list_interrupt_next(it); - } - } - } - - osMutexRelease(interrupt_mutex); + furi_assert(type < InterruptTypeLast); + if(callback_list[type].callback != NULL) { + furi_check(callback_list[type].callback == callback); } + + callback_list[type].ready = false; + __DMB(); + callback_list[type].callback = NULL; + callback_list[type].context = NULL; } void api_interrupt_enable(InterruptCallback callback, InterruptType type) { - if(osMutexAcquire(interrupt_mutex, osWaitForever) == osOK) { - list_interrupt_t* list = dict_interrupt_get(interrupts_dict, (uint32_t)type); + furi_assert(type < InterruptTypeLast); + furi_check(callback_list[type].callback == callback); - if(list != NULL) { - // iterate over items - list_interrupt_it_t it; - for(list_interrupt_it(it, *list); !list_interrupt_end_p(it); list_interrupt_next(it)) { - // if the iterator is equal to our element - if(it->current->data.callback == callback) { - it->current->data.ready = true; - asm volatile("dmb" : : : "memory"); - } - } - } - - osMutexRelease(interrupt_mutex); - } + callback_list[type].ready = true; + __DMB(); } void api_interrupt_disable(InterruptCallback callback, InterruptType type) { - if(osMutexAcquire(interrupt_mutex, osWaitForever) == osOK) { - list_interrupt_t* list = dict_interrupt_get(interrupts_dict, (uint32_t)type); + furi_assert(type < InterruptTypeLast); + furi_check(callback_list[type].callback == callback); - if(list != NULL) { - // iterate over items - list_interrupt_it_t it; - for(list_interrupt_it(it, *list); !list_interrupt_end_p(it); list_interrupt_next(it)) { - // if the iterator is equal to our element - if(it->current->data.callback == callback) { - it->current->data.ready = false; - asm volatile("dmb" : : : "memory"); - } - } - } - - osMutexRelease(interrupt_mutex); - } + callback_list[type].ready = false; + __DMB(); } 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 + furi_assert(type < InterruptTypeLast); - list_interrupt_t* list = dict_interrupt_get(interrupts_dict, (uint32_t)type); - - if(list != NULL) { - // iterate over items - list_interrupt_it_t it; - for(list_interrupt_it(it, *list); !list_interrupt_end_p(it); list_interrupt_next(it)) { - // if the iterator is equal to our element - if(it->current->data.ready) { - it->current->data.callback(hw, it->current->data.context); - } + if(callback_list[type].callback != NULL) { + if(callback_list[type].ready) { + callback_list[type].callback(hw, callback_list[type].context); } } } diff --git a/core/api-hal/api-interrupt-mgr.h b/core/api-hal/api-interrupt-mgr.h index fb6ffdabb..81245cb9d 100644 --- a/core/api-hal/api-interrupt-mgr.h +++ b/core/api-hal/api-interrupt-mgr.h @@ -12,14 +12,13 @@ typedef void (*InterruptCallback)(void*, void*); /** Interupt type */ typedef enum { InterruptTypeComparatorTrigger, - InterruptTypeTimerOutputCompare, InterruptTypeTimerUpdate, + InterruptTypeLast, } InterruptType; /** Interrupt callback type */ typedef struct { InterruptCallback callback; - InterruptType type; void* context; bool ready; } InterruptCallbackItem; diff --git a/firmware/targets/f5/api-hal/api-interrupts.c b/firmware/targets/f5/api-hal/api-interrupts.c index e92df4b9d..4fd90716f 100644 --- a/firmware/targets/f5/api-hal/api-interrupts.c +++ b/firmware/targets/f5/api-hal/api-interrupts.c @@ -10,11 +10,6 @@ void HAL_COMP_TriggerCallback(COMP_HandleTypeDef* hcomp) { api_interrupt_call(InterruptTypeComparatorTrigger, hcomp); } -/* Output compare event */ -void HAL_TIM_OC_DelayElapsedCallback(TIM_HandleTypeDef* htim) { - api_interrupt_call(InterruptTypeTimerOutputCompare, htim); -} - /* Timer update event */ void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef* htim) { api_interrupt_call(InterruptTypeTimerUpdate, htim); diff --git a/firmware/targets/f6/api-hal/api-interrupts.c b/firmware/targets/f6/api-hal/api-interrupts.c index e92df4b9d..4fd90716f 100644 --- a/firmware/targets/f6/api-hal/api-interrupts.c +++ b/firmware/targets/f6/api-hal/api-interrupts.c @@ -10,11 +10,6 @@ void HAL_COMP_TriggerCallback(COMP_HandleTypeDef* hcomp) { api_interrupt_call(InterruptTypeComparatorTrigger, hcomp); } -/* Output compare event */ -void HAL_TIM_OC_DelayElapsedCallback(TIM_HandleTypeDef* htim) { - api_interrupt_call(InterruptTypeTimerOutputCompare, htim); -} - /* Timer update event */ void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef* htim) { api_interrupt_call(InterruptTypeTimerUpdate, htim);