api-interrupt-mgr.c 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. #include "api-interrupt-mgr.h"
  2. #include <m-list.h>
  3. #include <cmsis_os2.h>
  4. LIST_DEF(list_interrupt, InterruptCallbackItem, M_POD_OPLIST);
  5. list_interrupt_t interrupts;
  6. osMutexId_t interrupt_list_mutex;
  7. bool api_interrupt_init() {
  8. interrupt_list_mutex = osMutexNew(NULL);
  9. return (interrupt_list_mutex != NULL);
  10. }
  11. void api_interrupt_add(InterruptCallback callback, InterruptType type, void* context) {
  12. if(osMutexAcquire(interrupt_list_mutex, osWaitForever) == osOK) {
  13. // put uninitialized item to the list
  14. // M_POD_OPLIST provide memset(&(a), 0, sizeof (a)) constructor
  15. // so item will not be ready until we set ready flag
  16. InterruptCallbackItem* item = list_interrupt_push_new(interrupts);
  17. // initialize item
  18. item->callback = callback;
  19. item->type = type;
  20. item->context = context;
  21. item->ready = true;
  22. // TODO remove on app exit
  23. //flapp_on_exit(api_interrupt_remove, callback);
  24. osMutexRelease(interrupt_list_mutex);
  25. }
  26. }
  27. void api_interrupt_remove(InterruptCallback callback) {
  28. if(osMutexAcquire(interrupt_list_mutex, osWaitForever) == osOK) {
  29. // iterate over items
  30. list_interrupt_it_t it;
  31. for(list_interrupt_it(it, interrupts); !list_interrupt_end_p(it);
  32. list_interrupt_next(it)) {
  33. const InterruptCallbackItem* item = list_interrupt_cref(it);
  34. // if the iterator is equal to our element
  35. if(item->callback == callback) {
  36. list_interrupt_remove(interrupts, it);
  37. break;
  38. }
  39. }
  40. osMutexRelease(interrupt_list_mutex);
  41. }
  42. }
  43. void api_interrupt_call(InterruptType type, void* hw) {
  44. // that executed in interrupt ctx so mutex don't needed
  45. // but we need to check ready flag
  46. // iterate over items
  47. list_interrupt_it_t it;
  48. for(list_interrupt_it(it, interrupts); !list_interrupt_end_p(it); list_interrupt_next(it)) {
  49. const InterruptCallbackItem* item = list_interrupt_cref(it);
  50. // if the iterator is equal to our element
  51. if(item->type == type && item->ready) {
  52. item->callback(hw, item->context);
  53. }
  54. }
  55. }