gpio-tester.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. #include <furi.h>
  2. #include <furi-hal.h>
  3. #include <gui/gui.h>
  4. #include <notification/notification-messages.h>
  5. typedef struct {
  6. const char* name;
  7. const GpioPin* pin;
  8. } GpioItem;
  9. static const GpioItem GPIO_PINS[] = {
  10. {"1.2: PA7", &gpio_ext_pa7},
  11. {"1.3: PA6", &gpio_ext_pa6},
  12. {"1.4: PA4", &gpio_ext_pa4},
  13. {"1.5: PB3", &gpio_ext_pb3},
  14. {"1.6: PB2", &gpio_ext_pb2},
  15. {"1.7: PC3", &gpio_ext_pc3},
  16. {"2.7: PC1", &gpio_ext_pc1},
  17. {"2.8: PC0", &gpio_ext_pc0},
  18. {"*.*: ALL", NULL},
  19. };
  20. static const size_t GPIO_PINS_COUNT = sizeof(GPIO_PINS) / sizeof(GPIO_PINS[0]);
  21. typedef struct {
  22. osMessageQueueId_t input_queue;
  23. uint8_t gpio_index;
  24. ViewPort* view_port;
  25. Gui* gui;
  26. NotificationApp* notification;
  27. } GpioTest;
  28. static void gpio_test_render_callback(Canvas* canvas, void* ctx) {
  29. GpioTest* gpio_test = ctx;
  30. canvas_clear(canvas);
  31. canvas_set_color(canvas, ColorBlack);
  32. canvas_set_font(canvas, FontPrimary);
  33. canvas_draw_str(canvas, 2, 10, "GPIO Control");
  34. canvas_set_font(canvas, FontSecondary);
  35. canvas_draw_str(canvas, 2, 25, GPIO_PINS[gpio_test->gpio_index].name);
  36. }
  37. static void gpio_test_input_callback(InputEvent* input_event, void* ctx) {
  38. GpioTest* gpio_test = ctx;
  39. osMessageQueuePut(gpio_test->input_queue, input_event, 0, 0);
  40. }
  41. static void gpio_test_configure_pins(GpioMode mode) {
  42. for(size_t i = 0; i < GPIO_PINS_COUNT; i++) {
  43. if(!GPIO_PINS[i].pin) continue;
  44. hal_gpio_write(GPIO_PINS[i].pin, false);
  45. hal_gpio_init(GPIO_PINS[i].pin, mode, GpioPullNo, GpioSpeedVeryHigh);
  46. }
  47. }
  48. static void gpio_test_set_pin(uint8_t index, bool level) {
  49. if(GPIO_PINS[index].pin) {
  50. hal_gpio_write(GPIO_PINS[index].pin, level);
  51. } else {
  52. for(size_t i = 0; i < GPIO_PINS_COUNT; i++) {
  53. if(!GPIO_PINS[i].pin) continue;
  54. hal_gpio_write(GPIO_PINS[i].pin, level);
  55. }
  56. }
  57. }
  58. GpioTest* gpio_test_alloc() {
  59. GpioTest* instance = furi_alloc(sizeof(GpioTest));
  60. gpio_test_configure_pins(GpioModeOutputPushPull);
  61. instance->input_queue = osMessageQueueNew(8, sizeof(InputEvent), NULL);
  62. furi_check(instance->input_queue);
  63. instance->view_port = view_port_alloc();
  64. view_port_draw_callback_set(instance->view_port, gpio_test_render_callback, instance);
  65. view_port_input_callback_set(instance->view_port, gpio_test_input_callback, instance);
  66. instance->gui = furi_record_open("gui");
  67. gui_add_view_port(instance->gui, instance->view_port, GuiLayerFullscreen);
  68. instance->notification = furi_record_open("notification");
  69. return instance;
  70. }
  71. void gpio_test_free(GpioTest* instance) {
  72. furi_assert(instance);
  73. furi_record_close("notification");
  74. view_port_enabled_set(instance->view_port, false);
  75. gui_remove_view_port(instance->gui, instance->view_port);
  76. furi_record_close("gui");
  77. view_port_free(instance->view_port);
  78. osMessageQueueDelete(instance->input_queue);
  79. gpio_test_configure_pins(GpioModeAnalog);
  80. free(instance);
  81. }
  82. int32_t gpio_test_app(void* p) {
  83. GpioTest* gpio_test = gpio_test_alloc();
  84. InputEvent event;
  85. while(osMessageQueueGet(gpio_test->input_queue, &event, NULL, osWaitForever) == osOK) {
  86. if(event.type == InputTypeShort) {
  87. if(event.key == InputKeyBack) {
  88. notification_message(gpio_test->notification, &sequence_reset_green);
  89. break;
  90. }
  91. if(event.key == InputKeyRight) {
  92. if(gpio_test->gpio_index < (GPIO_PINS_COUNT - 1)) {
  93. gpio_test->gpio_index++;
  94. }
  95. }
  96. if(event.key == InputKeyLeft) {
  97. if(gpio_test->gpio_index > 0) {
  98. gpio_test->gpio_index--;
  99. }
  100. }
  101. } else {
  102. if(event.key == InputKeyOk) {
  103. if(event.type == InputTypePress) {
  104. gpio_test_set_pin(gpio_test->gpio_index, true);
  105. notification_message(gpio_test->notification, &sequence_set_green_255);
  106. } else if(event.type == InputTypeRelease) {
  107. gpio_test_set_pin(gpio_test->gpio_index, false);
  108. notification_message(gpio_test->notification, &sequence_reset_green);
  109. }
  110. }
  111. }
  112. view_port_update(gpio_test->view_port);
  113. }
  114. gpio_test_free(gpio_test);
  115. return 0;
  116. }