gpio-tester.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. #include "flipper_v2.h"
  2. typedef struct {
  3. const char* name;
  4. GpioPin pin;
  5. } GpioItem;
  6. const GpioItem GPIO_PINS[] = {
  7. {"1.2: PA7", {GPIOA, GPIO_PIN_7}},
  8. {"1.3: PA6", {GPIOA, GPIO_PIN_6}},
  9. {"1.4: PA5", {GPIOA, GPIO_PIN_5}},
  10. {"1.5: PA4", {GPIOA, GPIO_PIN_4}},
  11. {"1.6: PB2", {GPIOB, GPIO_PIN_2}},
  12. {"1.7: PC3", {GPIOC, GPIO_PIN_3}},
  13. {"2.7: PC1", {GPIOC, GPIO_PIN_1}},
  14. {"2.8: PC0", {GPIOC, GPIO_PIN_0}},
  15. };
  16. typedef enum {
  17. EventTypeTick,
  18. EventTypeKey,
  19. } EventType;
  20. typedef struct {
  21. union {
  22. InputEvent input;
  23. } value;
  24. EventType type;
  25. } AppEvent;
  26. typedef struct {
  27. uint8_t gpio_index;
  28. } State;
  29. static void render_callback(Canvas* canvas, void* ctx) {
  30. State* state = (State*)acquire_mutex((ValueMutex*)ctx, 25);
  31. canvas_clear(canvas);
  32. canvas_set_color(canvas, ColorBlack);
  33. canvas_set_font(canvas, FontPrimary);
  34. canvas_draw_str(canvas, 2, 10, "GPIO demo");
  35. canvas_set_font(canvas, FontSecondary);
  36. canvas_draw_str(canvas, 2, 25, GPIO_PINS[state->gpio_index].name);
  37. release_mutex((ValueMutex*)ctx, state);
  38. }
  39. static void input_callback(InputEvent* input_event, void* ctx) {
  40. osMessageQueueId_t event_queue = (QueueHandle_t)ctx;
  41. AppEvent event;
  42. event.type = EventTypeKey;
  43. event.value.input = *input_event;
  44. osMessageQueuePut(event_queue, &event, 0, 0);
  45. }
  46. void app_gpio_test(void* p) {
  47. osMessageQueueId_t event_queue = osMessageQueueNew(1, sizeof(AppEvent), NULL);
  48. furi_check(event_queue);
  49. State _state;
  50. _state.gpio_index = 0;
  51. ValueMutex state_mutex;
  52. if(!init_mutex(&state_mutex, &_state, sizeof(State))) {
  53. printf("[gpio-tester] cannot create mutex\n");
  54. furiac_exit(NULL);
  55. }
  56. Widget* widget = widget_alloc();
  57. widget_draw_callback_set(widget, render_callback, &state_mutex);
  58. widget_input_callback_set(widget, input_callback, event_queue);
  59. // Open GUI and register widget
  60. Gui* gui = (Gui*)furi_open("gui");
  61. if(gui == NULL) {
  62. printf("[gpio-tester] gui is not available\n");
  63. furiac_exit(NULL);
  64. }
  65. gui_add_widget(gui, widget, GuiLayerFullscreen);
  66. // configure pin
  67. for(uint8_t i = 0; i < sizeof(GPIO_PINS) / sizeof(GPIO_PINS[0]); i++) {
  68. gpio_init((GpioPin*)&GPIO_PINS[i].pin, GpioModeOutputPushPull);
  69. }
  70. gpio_init((GpioPin*)&led_gpio[1], GpioModeOutputOpenDrain);
  71. AppEvent event;
  72. while(1) {
  73. osStatus_t event_status = osMessageQueueGet(event_queue, &event, NULL, 150);
  74. State* state = (State*)acquire_mutex_block(&state_mutex);
  75. if(event_status == osOK) {
  76. if(event.type == EventTypeKey) {
  77. if(event.value.input.state && event.value.input.input == InputBack) {
  78. printf("[gpio-tester] bye!\n");
  79. // TODO remove all widgets create by app
  80. widget_enabled_set(widget, false);
  81. furiac_exit(NULL);
  82. }
  83. if(event.value.input.state && event.value.input.input == InputRight) {
  84. if(state->gpio_index < (sizeof(GPIO_PINS) / sizeof(GPIO_PINS[0]) - 1)) {
  85. state->gpio_index++;
  86. }
  87. }
  88. if(event.value.input.state && event.value.input.input == InputLeft) {
  89. if(state->gpio_index > 0) {
  90. state->gpio_index--;
  91. }
  92. }
  93. if(event.value.input.input == InputOk) {
  94. gpio_write(
  95. (GpioPin*)&GPIO_PINS[state->gpio_index].pin, event.value.input.state);
  96. gpio_write((GpioPin*)&led_gpio[1], !event.value.input.state);
  97. }
  98. }
  99. }
  100. release_mutex(&state_mutex, state);
  101. widget_update(widget);
  102. }
  103. }