gpio_reader.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. #include "gpio_reader.h"
  2. #include "../gpio_item.h"
  3. #include <gui/elements.h>
  4. #include <furi_hal_resources.h>
  5. struct GpioReader {
  6. View* view;
  7. GpioReaderOkCallback callback;
  8. void* context;
  9. };
  10. typedef struct {
  11. uint8_t pin_idx;
  12. bool pullUp[GPIO_ITEM_COUNT];
  13. } GpioReaderModel;
  14. static bool gpio_reader_process_ok(GpioReader* gpio_reader, InputEvent* event);
  15. static bool gpio_reader_process_left(GpioReader* gpio_reader);
  16. static bool gpio_reader_process_right(GpioReader* gpio_reader);
  17. static void gpio_reader_draw_callback(Canvas* canvas, void* _model) {
  18. GpioReaderModel* model = _model;
  19. canvas_set_font(canvas, FontPrimary);
  20. elements_multiline_text_aligned(canvas, 64, 2, AlignCenter, AlignTop, "GPIO Reader");
  21. canvas_set_font(canvas, FontSecondary);
  22. elements_multiline_text_aligned(
  23. canvas, 64, 16, AlignCenter, AlignTop, "A7 A6 A4 B3 B2 C3 C1 C0");
  24. elements_multiline_text_aligned(
  25. canvas, 64, 40, AlignCenter, AlignTop, "Pull Up");
  26. int charOffset = 10;
  27. for(uint8_t i = 0; i < GPIO_ITEM_COUNT; i++) {
  28. bool high = gpio_item_get_pin(i);
  29. if(high) {
  30. elements_multiline_text_aligned(
  31. canvas, charOffset, 25, AlignCenter, AlignTop, "1");
  32. } else {
  33. elements_multiline_text_aligned(
  34. canvas, charOffset, 25, AlignCenter, AlignTop, "0");
  35. }
  36. if(model->pullUp[i]) {
  37. elements_multiline_text_aligned(
  38. canvas, charOffset, 50, AlignCenter, AlignTop, "1");
  39. } else {
  40. elements_multiline_text_aligned(
  41. canvas, charOffset, 50, AlignCenter, AlignTop, "0");
  42. }
  43. if(i == model->pin_idx) {
  44. elements_multiline_text_aligned(
  45. canvas, charOffset, 53, AlignCenter, AlignTop, "_");
  46. }
  47. charOffset += 16;
  48. }
  49. //~ free(charOffset);
  50. }
  51. static bool gpio_reader_input_callback(InputEvent* event, void* context) {
  52. furi_assert(context);
  53. GpioReader* gpio_reader = context;
  54. bool consumed = false;
  55. if(event->type == InputTypeShort) {
  56. if(event->key == InputKeyRight) {
  57. consumed = gpio_reader_process_right(gpio_reader);
  58. } else if(event->key == InputKeyLeft) {
  59. consumed = gpio_reader_process_left(gpio_reader);
  60. }
  61. } else if(event->key == InputKeyOk) {
  62. consumed = gpio_reader_process_ok(gpio_reader, event);
  63. }
  64. return consumed;
  65. }
  66. static bool gpio_reader_process_left(GpioReader* gpio_reader) {
  67. with_view_model(
  68. gpio_reader->view,
  69. GpioReaderModel * model,
  70. {
  71. if(model->pin_idx) {
  72. model->pin_idx--;
  73. }
  74. },
  75. true);
  76. return true;
  77. }
  78. static bool gpio_reader_process_right(GpioReader* gpio_reader) {
  79. with_view_model(
  80. gpio_reader->view,
  81. GpioReaderModel * model,
  82. {
  83. if(model->pin_idx < GPIO_ITEM_COUNT-1) {
  84. model->pin_idx++;
  85. }
  86. },
  87. true);
  88. return true;
  89. }
  90. static bool gpio_reader_process_ok(GpioReader* gpio_reader, InputEvent* event) {
  91. bool consumed = false;
  92. with_view_model(
  93. gpio_reader->view,
  94. GpioReaderModel * model,
  95. {
  96. if(event->type == InputTypePress) {
  97. if(model->pullUp[model->pin_idx]){
  98. gpio_item_configure_pin(model->pin_idx, GpioModeInput, GpioPullDown);
  99. model->pullUp[model->pin_idx] = 0;
  100. consumed = true;
  101. }else{
  102. gpio_item_configure_pin(model->pin_idx, GpioModeInput, GpioPullUp);
  103. model->pullUp[model->pin_idx] = 1;
  104. consumed = true;
  105. }
  106. }
  107. gpio_reader->callback(event->type, gpio_reader->context);
  108. },
  109. true);
  110. return consumed;
  111. }
  112. GpioReader* gpio_reader_alloc() {
  113. GpioReader* gpio_reader = malloc(sizeof(GpioReader));
  114. gpio_reader->view = view_alloc();
  115. view_allocate_model(gpio_reader->view, ViewModelTypeLocking, sizeof(GpioReaderModel));
  116. view_set_context(gpio_reader->view, gpio_reader);
  117. view_set_draw_callback(gpio_reader->view, gpio_reader_draw_callback);
  118. view_set_input_callback(gpio_reader->view, gpio_reader_input_callback);
  119. return gpio_reader;
  120. }
  121. void gpio_reader_free(GpioReader* gpio_reader) {
  122. furi_assert(gpio_reader);
  123. view_free(gpio_reader->view);
  124. free(gpio_reader);
  125. }
  126. View* gpio_reader_get_view(GpioReader* gpio_reader) {
  127. furi_assert(gpio_reader);
  128. return gpio_reader->view;
  129. }
  130. void gpio_reader_set_ok_callback(GpioReader* gpio_reader, GpioReaderOkCallback callback, void* context) {
  131. furi_assert(gpio_reader);
  132. furi_assert(callback);
  133. with_view_model(
  134. gpio_reader->view,
  135. GpioReaderModel * model,
  136. {
  137. UNUSED(model);
  138. gpio_reader->callback = callback;
  139. gpio_reader->context = context;
  140. },
  141. false);
  142. }